المصادقة في Firebase باستخدام رابط البريد الإلكتروني في Android

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

هناك عدة مزايا لتسجيل الدخول عبر البريد الإلكتروني:

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

قبل البدء

إعداد مشروع Android

  1. إذا لم تكن قد فعلت ذلك بالفعل، إضافة Firebase إلى مشروع Android

  2. في ملف Gradle للوحدة (على مستوى التطبيق) (عادةً <project>/<app-module>/build.gradle.kts أو <project>/<app-module>/build.gradle)، أضف التبعية لمكتبة مصادقة Firebase لنظام Android. ننصح باستخدام قائمة مواد العرض لنظام Android في Firebase للتحكم في إصدارات المكتبة.

    وكجزء من إعداد مصادقة Firebase أيضًا، يلزمك إضافة حزمة تطوير البرامج (SDK) الخاصة "بخدمات Google Play" إلى تطبيقك

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.1.2"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.2.0")
    }

    باستخدام قائمة قائمتها التشغيلية (Android BoM) من Firebase سيستخدم تطبيقك دائمًا إصدارات متوافقة من مكتبات Android في Firebase.

    (بديل) إضافة تبعيات مكتبة Firebase بدون استخدام BoM

    إذا اخترت عدم استخدام قائمة عناصر Firebase، يجب تحديد كل إصدار من إصدارات مكتبة Firebase. في سطر التبعية.

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

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:23.0.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.2.0")
    }
    هل تبحث عن وحدة مكتبة خاصة بلغة Kotlin؟ ستبدأ بعد تشرين الأول (أكتوبر) 2023 (الإصدار 32.5.0 من Firebase BoM)، بإمكان مطوّري برامج Kotlin وJava تعتمد على وحدة المكتبة الرئيسية (لمزيد من التفاصيل، راجع الأسئلة الشائعة حول هذه المبادرة).

لتسجيل دخول المستخدمين عبر رابط البريد الإلكتروني، يجب أولاً تفعيل مزوِّد خدمة البريد الإلكتروني طريقة تسجيل الدخول باستخدام رابط البريد الإلكتروني لمشروع Firebase:

  1. في وحدة تحكُّم Firebase، افتح قسم المصادقة.
  2. في علامة التبويب طريقة تسجيل الدخول، فعِّل مزوِّد البريد الإلكتروني/كلمة المرور. ملاحظة أنه يجب تفعيل تسجيل الدخول باستخدام عنوان البريد الإلكتروني/كلمة المرور لاستخدام ميزة تسجيل الدخول باستخدام رابط البريد الإلكتروني.
  3. في القسم نفسه، فعِّل تسجيل الدخول باستخدام رابط البريد الإلكتروني (تسجيل الدخول بدون كلمة مرور). .
  4. انقر على حفظ.

لبدء عملية المصادقة، قدِّم للمستخدم واجهة مطالبة المستخدم بتقديم عنوان بريده الإلكتروني ثم الاتصال sendSignInLinkToEmail لتطلب من Firebase إرسال رابط المصادقة إلى عنوان البريد الإلكتروني للمستخدم.

  1. إنشاء ActionCodeSettings يزوِّد Firebase بتعليمات عن كيفية إنشاء . اضبط الحقول التالية:

    • url: هو الرابط لصفحة معيّنة التي سيتم تضمينها وأي حالة إضافية يجب تمريرها. يجب إضافة نطاق الرابط إلى القائمة البيضاء في قائمة وحدة تحكُّم Firebase النطاقات المسموح بها، والتي يمكن العثور عليها بالانتقال إلى علامة التبويب "طريقة تسجيل الدخول" (المصادقة -> طريقة تسجيل الدخول). سيعيد الرابط توجيه المستخدم إلى عنوان URL هذا إذا لم يتم تثبيت التطبيق على أجهزتهم ولم يتم يمكن تثبيته.
    • androidPackageName وIOSBundleId: التطبيقان اللذان يمكنك استخدامهما عند تسجيل الدخول على جهاز Android أو Apple. يُرجى الاطّلاع على مزيد من المعلومات حول كيفية إعداد روابط Firebase الديناميكية لفتح روابط إجراءات البريد الإلكتروني عبر التطبيقات للأجهزة الجوّالة.
    • handleCodeInApp: تم ضبطها على "صحيح". يجب أن تكون عملية تسجيل الدخول دائمًا في التطبيق على عكس إجراءات البريد الإلكتروني الأخرى خارج النطاق (كلمة المرور) إعادة الضبط وعمليات إثبات ملكية البريد الإلكتروني). هذا لأنه في نهاية التدفق، يُتوقع من المستخدم تسجيل الدخول واستمرار حالة المصادقة خلال التطبيق.
    • dynamicLinkDomain: عند تحديد عدة نطاقات روابط ديناميكية مخصّصة بالنسبة لمشروع ما، فحدِّد أيًا منها سيتم استخدامه عند فتح الرابط عبر تطبيق جوّال محدّد (مثلاً، example.page.link). بخلاف ذلك يتم اختيار النطاق الأول تلقائيًا.

    Kotlin+KTX

    val actionCodeSettings = actionCodeSettings {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url = "https://www.example.com/finishSignUp?cartId=1234"
        // This must be true
        handleCodeInApp = true
        setIOSBundleId("com.example.ios")
        setAndroidPackageName(
            "com.example.android",
            true, // installIfNotAvailable
            "12", // minimumVersion
        )
    }

    Java

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    لمزيد من المعلومات حول ActionCodeSettings، يمكنك الرجوع إلى حالة اجتياز الاختبار في إجراءات البريد الإلكتروني .

  2. اطلب من المستخدم إدخال بريده الإلكتروني.

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

    Kotlin+KTX

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Email sent.")
            }
        }

    Java

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

المخاوف المرتبطة بالأمان

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

ويمكنك تبسيط هذا المسار للمستخدمين الذين يفتحون رابط تسجيل الدخول على جهاز يطلبون الرابط، عن طريق تخزين عنوان بريدهم الإلكتروني محليًا - لمدة مثال باستخدام SharedPreferences - عند إرسالك عنوان البريد الإلكتروني لتسجيل الدخول. بعد ذلك، يُرجى اتّباع الخطوات التالية: استخدم هذا العنوان لإكمال التدفق. لا تمرّر عنوان البريد الإلكتروني للمستخدم في معلَمات عنوان URL لإعادة التوجيه وتعيد استخدامه فقد يؤدي ذلك إلى تفعيل حقن الجلسات.

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

احرص أيضًا على استخدام عنوان URL يستخدم HTTPS في مرحلة الإنتاج لتجنّب استخدام الرابط من المحتمل أن تعترضها الخوادم الوسيطة.

إكمال تسجيل الدخول في تطبيق Android

تستخدم مصادقة Firebase روابط Firebase الديناميكية لإرسال رابط الرسالة الإلكترونية إلى جهاز جوّال. لإكمال عملية تسجيل الدخول عبر تطبيق الأجهزة الجوّالة، يجب تقديم طلب لاكتشاف رابط التطبيق الوارد، وتحليل رابط لصفحة في التطبيق الأساسي ثم إكمال عملية تسجيل الدخول.

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

  1. تفعيل روابط Firebase الديناميكية:

    1. في وحدة تحكُّم Firebase، افتح قسم الروابط الديناميكية.
    2. في حال عدم قبولك بنود "الروابط الديناميكية" بعد وإنشاء روابط ديناميكية مجالك، قم بذلك الآن.

      إذا سبق لك إنشاء نطاق "روابط ديناميكية"، دوِّنه. الروابط الديناميكية على النحو التالي:

      example.page.link

      ستحتاج إلى هذه القيمة عند ضبط تطبيق Apple أو Android على لاعتراض الرابط الوارد.

  2. تهيئة تطبيقات Android:

    1. لمعالجة هذه الروابط من تطبيق Android، يجب أولاً يجب تحديد اسم حزمة Android في وحدة تحكُّم Firebase. إعدادات المشروع. بالإضافة إلى ذلك، SHA-1 وSHA-256 للتطبيق الشهادة اللازمة.
    2. والآن بعد أن أضفتَ نطاق رابط ديناميكي وتأكدتَ من أن تم إعداد تطبيق Android بشكل صحيح، ستتم إعادة توجيه الرابط الديناميكي إلى تطبيقك، بدءًا من نشاط المشغّل.
    3. إذا أردت أن يُعيد الرابط الديناميكي التوجيه إلى نشاط معين، عليك ضبط فلتر أهداف في ملف AndroidManifest.xml الملف. ويمكن إجراء ذلك عن طريق تحديد نطاق الرابط الديناميكي أو معالج إجراء البريد الإلكتروني في فلتر الأهداف. بشكل افتراضي، تتم استضافة معالج الإجراءات على نطاق مثل المثال التالي:
      PROJECT_ID.firebaseapp.com/
    4. محاذير:
      1. لا تحدِّد عنوان URL الذي أعددته في actionCodeSettings في فلتر الأهداف.
      2. عند إنشاء نطاق رابط ديناميكي، ربما تكون قد أنشأت أيضًا نطاق رابط عنوان URL مختصر. لن يتم تمرير عنوان URL المختصر هذا؛ لا تفعل اضبط فلتر الأهداف لرصده من خلال android:pathPrefix. هذا يعني أنك سوف لن يكونوا قادرين على التقاط روابط ديناميكية مختلفة في أجزاء مختلفة من تطبيقك. ومع ذلك، يمكنك التحقّق من معلَمة طلب البحث mode. في الرابط لمعرفة العملية التي يحاول تنفيذها، أو استخدام طرق حزمة تطوير البرامج (SDK) مثل isSignInWithEmailLink لمعرفة ما إذا الرابط الذي تلقاه تطبيقك يفعل ما تريده.
    5. لمزيد من المعلومات حول تلقّي روابط ديناميكية، يمكنك الاطّلاع على تلقّي تعليمات بشأن ميزة "الروابط الديناميكية على Android"

بعد تلقّي الرابط كما هو موضّح أعلاه، تحقّق من أنّه مخصّص للبريد الإلكتروني. مصادقة الرابط وأكمل عملية تسجيل الدخول.

Kotlin+KTX

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully signed in with email link!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error signing in with email link", task.exception)
            }
        }
}

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

مزيد من المعلومات حول كيفية التعامل مع تسجيل الدخول باستخدام رابط بريد إلكتروني في Apple راجع دليل أنظمة التشغيل Apple.

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

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

سيكون الاختلاف في النصف الثاني من العملية:

Kotlin+KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            Log.d(TAG, "Successfully linked emailLink credential!")
            val result = task.result
            // You can access the new user via result.getUser()
            // Additional user info profile *not* available via:
            // result.getAdditionalUserInfo().getProfile() == null
            // You can check if the user is new or existing:
            // result.getAdditionalUserInfo().isNewUser()
        } else {
            Log.e(TAG, "Error linking emailLink credential", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

ويمكن استخدامها أيضًا لإعادة مصادقة مستخدم رابط البريد الإلكتروني قبل تشغيل عملية حساسة.

Kotlin+KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            // User is now successfully reauthenticated
        } else {
            Log.e(TAG, "Error reauthenticating", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

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

إذا أنشأت مشروعك في 15 أيلول (سبتمبر) 2023 أو بعده، يجب تعداد البريد الإلكتروني تكون ميزة "توفير السلامة تلقائيًا" مفعَّلة تلقائيًا تعمل هذه الميزة على تحسين أمان في المشروع، ولكن سيتم إيقاف fetchSignInMethodsForEmail() التي اقترحناها سابقًا لتنفيذ تدفقات المُعرّف أولاً.

على الرغم من أنّه يمكنك إيقاف حماية تعداد البريد الإلكتروني في مشروعك، أن نوصي بعدم القيام بذلك.

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

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

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

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

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

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

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

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();