المصادقة باستخدام OpenID Connect على Android

في حال الترقية إلى Firebase Authentication with Identity Platform، يمكنك مصادقة المستخدمين من خلال Firebase باستخدام الموفّر المتوافق مع OpenID Connect (OIDC) الذي تختاره. هذا النمط تُتيح استخدام موفّري هوية غير معتمدين في Firebase في الأصل.

قبل البدء

لتسجيل دخول المستخدمين باستخدام موفِّر OIDC، عليك أولاً جمع بعض المعلومات. من المزود:

  • Client-ID (رقم تعريف العميل): سلسلة فريدة للمقدّم الذي يعرّف تطبيقك. يمكن أن يعيّن لك مزوّد الخدمة معرّف عميل مختلف لكل نظام أساسي تدعمه. هذه إحدى قيم المطالبة "aud" في الرموز المميّزة للمعرّف الصادر عن المستخدم.

  • سر العميل: سلسلة سرية يستخدمها موفّر الخدمة لتأكيد الملكية لمعرف العميل. يجب توفير سر عميل مطابق لكل معرِّف عميل. (هذه القيمة مطلوبة فقط إذا كنت تستخدم مسار رمز المصادقة، وهو ننصح باستخدامها بشدة).

  • جهة الإصدار: سلسلة تحدِّد هوية مقدّم الخدمة. يجب أن تكون هذه القيمة عنوان URL يشير إلى الموقع الجغرافي عند إلحاقه بـ /.well-known/openid-configuration مستند اكتشاف OIDC الخاص بمزود الخدمة. على سبيل المثال، إذا كانت جهة الإصدار https://auth.example.com، يجب أن يكون مستند Discovery متاحًا على https://auth.example.com/.well-known/openid-configuration

بعد حصولك على المعلومات المذكورة أعلاه، فعّل OpenID Connect كتسجيل دخول. مقدم الخدمة لمشروعك على Firebase:

  1. أضِف Firebase إلى مشروع Android.

  2. في حال عدم الترقية إلى Firebase Authentication with Identity Platform، يُرجى إجراء ذلك. مصادقة OpenID Connect لا تتوفّر إلا في المشاريع التي تمت ترقيتها.

  3. على مقدّمي الخدمات الذين يسجّلون الدخول في وحدة تحكم Firebase، وانقر على إضافة موفِّر جديد، ثم انقر على ربط OpenID.

  4. اختَر ما إذا كنت ستستخدم مسار رمز التفويض أو تدفق المنح الضمني

    يجب استخدام مسار الرمز دائمًا إذا كان مقدّم الخدمة يتيح ذلك. تشير رسالة الأشكال البيانية التدفق الضمني أقل أمانًا ولا ننصح باستخدامه بشدة.

  5. يُرجى تسمية مقدّم الخدمة هذا. دوِّن رقم تعريف موفّر الخدمة الذي يتم إنشاؤه: شيء مثل oidc.example-provider. ستحتاج إلى رقم التعريف هذا عند إضافة رمز تسجيل الدخول إلى تطبيقك.

  6. حدِّد معرّف العميل وسر العميل وسلسلة جهة الإصدار الخاصة بموفِّر الخدمة. يجب أن تتطابق هذه القيم تمامًا مع القيم التي عيّنها لك مزوّد الخدمة.

  7. احفظ التغييرات.

معالجة عملية تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) لمنصّة Firebase

إنّ أسهل طريقة لمصادقة المستخدمين في حال إنشاء تطبيق Android. مع Firebase باستخدام مزود OIDC هو معالجة عملية تسجيل الدخول بالكامل حزمة تطوير البرامج (SDK) لنظام التشغيل Android لمنصة Firebase.

لمعالجة عملية تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل Android لمنصة Firebase، اتّبِع الخطوات التالية:

  1. يمكنك إنشاء نسخة افتراضية من OAuthProvider باستخدام Builder التابع له مع رقم تعريف مقدّم الخدمة

    Kotlin+KTX

    val providerBuilder = OAuthProvider.newBuilder("oidc.example-provider")

    Java

    OAuthProvider.Builder providerBuilder = OAuthProvider.newBuilder("oidc.example-provider");

  2. اختياري: تحديد مَعلمات OAuth المخصَّصة الإضافية التي تريد الإرسال باستخدام طلب OAuth.

    Kotlin+KTX

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com")

    Java

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com");

    تواصَل مع مزوّد OIDC لمعرفة المَعلمات التي يوفّرها. تجدر الإشارة إلى أنّه لا يمكنك تمرير المَعلمات المطلوبة في Firebase مع setCustomParameters() هذه المَعلمات هي client_id response_type وredirect_uri وstate وscope response_mode.

  3. اختياري: حدِّد نطاقات OAuth 2.0 الإضافية بخلاف الملف الشخصي الأساسي الذي التي ترغب في طلبها من مُقدِّم خدمة المصادقة.

    Kotlin+KTX

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    providerBuilder.scopes = listOf("mail.read", "calendars.read")

    Java

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    List<String> scopes =
            new ArrayList<String>() {
                {
                    add("mail.read");
                    add("calendars.read");
                }
            };
    providerBuilder.setScopes(scopes);

    تواصَل مع موفِّر OIDC لمعرفة النطاقات التي يستخدمها.

  4. عليك المصادقة مع Firebase باستخدام كائن موفّر بروتوكول OAuth. لاحظ أنه على عكس مصادقة FirebaseAuth الأخرى العمليات، سيتحكم هذا في واجهة المستخدم من خلال ظهور علامة تبويب Chrome مخصَّصة. ونتيجةً لذلك، يُرجى عدم الإشارة إلى نشاطك في OnSuccessListener. وOnFailureListener التي ترفقها لأنه سيتم فصلها على الفور عند تبدأ العملية واجهة المستخدم.

    يجب أولاً التحقّق مما إذا كنت قد تلقّيت ردًا. تسجيل الدخول باستخدام تضع هذه الطريقة نشاطك في الخلفية، مما يعني أنه يمكن من خلال النظام أثناء عملية تسجيل الدخول. من أجل التأكد من يجب ألا تجعل المستخدم يحاول مرة أخرى في حالة حدوث ذلك، فيجب التحقق من النتيجة موجودة بالفعل.

    لمعرفة ما إذا كانت هناك نتيجة معلّقة، يمكنك الاتصال على getPendingAuthResult:

    Kotlin+KTX

    val pendingResultTask = firebaseAuth.pendingAuthResult
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
            .addOnSuccessListener {
                // User is signed in.
                // IdP data available in
                // authResult.getAdditionalUserInfo().getProfile().
                // The OAuth access token can also be retrieved:
                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                // The OAuth secret can be retrieved by calling:
                // ((OAuthCredential)authResult.getCredential()).getSecret().
            }
            .addOnFailureListener {
                // Handle failure.
            }
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Java

    Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
                .addOnSuccessListener(
                        new OnSuccessListener<AuthResult>() {
                            @Override
                            public void onSuccess(AuthResult authResult) {
                                // User is signed in.
                                // IdP data available in
                                // authResult.getAdditionalUserInfo().getProfile().
                                // The OAuth access token can also be retrieved:
                                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                                // The OAuth secret can be retrieved by calling:
                                // ((OAuthCredential)authResult.getCredential()).getSecret().
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                // Handle failure.
                            }
                        });
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    لبدء عملية تسجيل الدخول، يمكنك الاتصال بالرقم startActivityForSignInWithProvider:

    Kotlin+KTX

    firebaseAuth
        .startActivityForSignInWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is signed in.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // ((OAuthCredential)authResult.getCredential()).getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    firebaseAuth
            .startActivityForSignInWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is signed in.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // ((OAuthCredential)authResult.getCredential()).getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  5. بينما تركز الأمثلة أعلاه على تدفقات تسجيل الدخول، لديك أيضًا إمكانية ربط موفر OIDC بمستخدم حالي باستخدام startActivityForLinkWithProvider على سبيل المثال، يمكنك ربط عدة مواقع مقدمي الخدمة للمستخدم نفسه مما يسمح لهم بتسجيل الدخول باستخدام أي منهما.

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForLinkWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // Provider credential is linked to the current user.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // authResult.getCredential().getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // authResult.getCredential().getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForLinkWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Provider credential is linked to the current user.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // authResult.getCredential().getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // authResult.getCredential().getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  6. يمكن استخدام نفس النمط مع startActivityForReauthenticateWithProvider الذي يمكن استخدامه لاسترداد بيانات اعتماد جديدة للعمليات الحساسة التي تتطلب تسجيل دخول مؤخرًا.

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForReauthenticateWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is re-authenticated with fresh tokens and
                            // should be able to perform sensitive operations
                            // like account deletion and email or password
                            // update.
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

معالجة عملية تسجيل الدخول يدويًا

إذا سبق لك تنفيذ خطوات تسجيل الدخول إلى OpenID Connect في تطبيقك، استخدام الرمز المميز للمعرّف مباشرةً للمصادقة مع Firebase:

Kotlin+KTX

val providerId = "oidc.example-provider" // As registered in Firebase console.
val credential = oAuthCredential(providerId) {
    setIdToken(idToken) // ID token from OpenID Connect flow.
}
Firebase.auth
    .signInWithCredential(credential)
    .addOnSuccessListener { authResult ->
        // User is signed in.

        // IdP data available in:
        //    authResult.additionalUserInfo.profile
    }
    .addOnFailureListener { e ->
        // Handle failure.
    }

Java

AuthCredential credential = OAuthProvider
        .newCredentialBuilder("oidc.example-provider")  // As registered in Firebase console.
        .setIdToken(idToken)  // ID token from OpenID Connect flow.
        .build();
FirebaseAuth.getInstance()
        .signInWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // User is signed in.

                // IdP data available in:
                //    authResult.getAdditionalUserInfo().getProfile()
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Handle failure.
            }
        });

الخطوات التالية

بعد تسجيل المستخدم الدخول لأول مرة، يتم إنشاء حساب مستخدم جديد المرتبطة ببيانات الاعتماد - أي اسم المستخدم وكلمة المرور، أو الرقم أو معلومات مقدم المصادقة - المستخدم الذي سجّل الدخول باستخدامه. هذا الجديد كجزء من مشروع Firebase، ويمكن استخدامه لتحديد مستخدم في كل تطبيق في مشروعك، بغض النظر عن كيفية تسجيل دخوله.

  • في تطبيقاتك، يمكنك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من الكائن FirebaseUser. عرض إدارة المستخدمين:

  • في Firebase Realtime Database وCloud Storage قواعد الأمان، تتيح لك الحصول على معرّف المستخدم الفريد للمستخدم الذي سجّل الدخول من المتغير auth، واستخدامها للتحكم في البيانات التي يمكن للمستخدم الوصول إليها

يمكنك السماح للمستخدمين بتسجيل الدخول إلى تطبيقك باستخدام طرق مصادقة متعددة. موفِّري خدمة المصادقة من خلال ربط بيانات اعتماد موفر المصادقة حساب مستخدم حالي

لتسجيل خروج مستخدم، اتصل بالرقم signOut:

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();