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

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

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

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

قبل البدء

  1. إذا لم يسبق لك ذلك، اتّبِع الخطوات الواردة في دليل البدء.

  2. فعِّل ميزة "تسجيل الدخول باستخدام رابط إلكتروني" لمشروعك على Firebase.

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

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

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

  1. أنشئ العنصر ActionCodeSettings الذي يقدّم إلى Firebase تعليمات حول كيفية إنشاء رابط البريد الإلكتروني. اضبط الحقول التالية:

    • url: الرابط لصفحة في التطبيق الذي سيتم تضمينه وأي حالة إضافية سيتم تمريرها. يجب أن يكون نطاق الرابط متوفّرًا في قائمة النطاقات المصرّح بها في وحدة تحكّم Firebase، ويمكنك العثور عليه من خلال الانتقال إلى علامة التبويب "الإعدادات" (المصادقة -> الإعدادات -> النطاقات المصرّح بها). ستتم إعادة توجيه المستخدم إلى عنوان URL هذا إذا لم يكن التطبيق مثبّتًا على جهازه ولم يكن من الممكن تثبيته.

    • androidPackageName وIOSBundleId: التطبيقات التي سيتم استخدامها عند فتح رابط تسجيل الدخول على جهاز Android أو iOS. تعرَّف على مزيد من المعلومات حول كيفية ضبط "روابط Firebase الديناميكية" لفتح روابط إجراءات البريد الإلكتروني من خلال تطبيقات الأجهزة الجوّالة.

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

    • dynamicLinkDomain: (تم إيقافها نهائيًا، استخدِم linkDomain) عند تحديد نطاقات مخصّصة متعددة للروابط الديناميكية لمشروع، حدِّد النطاق الذي تريد استخدامه عند فتح الرابط باستخدام تطبيق محدّد على الأجهزة الجوّالة (على سبيل المثال، example.page.link). وإلا سيتم تلقائيًا اختيار النطاق الأول.

    • linkDomain: نطاق Firebase Hosting المخصّص الاختياري الذي سيتم استخدامه عند فتح الرابط باستخدام تطبيق محدّد على الأجهزة الجوّالة. يجب ضبط النطاق في Firebase Hosting وأن يكون مملوكًا للمشروع. لا يمكن أن يكون هذا نطاق استضافة تلقائيًا (web.app أو firebaseapp.com). يحلّ هذا الإعداد محلّ الإعداد dynamicLinkDomain المتوقّف نهائيًا.

    var acs = 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,
        iOSBundleId: 'com.example.ios',
        androidPackageName: 'com.example.android',
        // installIfNotAvailable
        androidInstallApp: true,
        // minimumVersion
        androidMinimumVersion: '12');
    
  2. اطلب من المستخدم إدخال عنوان بريده الإلكتروني.

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

    var emailAuth = 'someemail@domain.com';
    FirebaseAuth.instance.sendSignInLinkToEmail(
            email: emailAuth, actionCodeSettings: acs)
        .catchError((onError) => print('Error sending email verification $onError'))
        .then((value) => print('Successfully sent email verification'));
    });
    

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

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

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

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

تأكَّد أيضًا من استخدام عنوان URL بتنسيق HTTPS في مرحلة الإنتاج لتجنُّب اعتراض الخوادم الوسيطة المحتمل لعنوان URL.

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

تم إيقاف ميزة "روابط Firebase الديناميكية" نهائيًا، ويتم الآن استخدام Firebase Hosting لإرسال رابط تسجيل الدخول. اتّبِع الأدلة الخاصة بإعداد المنصة:

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

  1. في معالج الروابط، تحقَّق مما إذا كان الرابط مخصّصًا للمصادقة باستخدام رابط إلكتروني، وإذا كان الأمر كذلك، أكمل عملية تسجيل الدخول.

    // Confirm the link is a sign-in with email link.
    if (FirebaseAuth.instance.isSignInWithEmailLink(emailLink)) {
      try {
        // The client SDK will parse the code from the link for you.
        final userCredential = await FirebaseAuth.instance
            .signInWithEmailLink(email: emailAuth, emailLink: emailLink);
    
        // You can access the new user via userCredential.user.
        final emailAddress = userCredential.user?.email;
    
        print('Successfully signed in with email link!');
      } catch (error) {
        print('Error signing in with email link.');
      }
    }
    

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

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

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.linkWithCredential(authCredential);
} catch (error) {
    print("Error linking emailLink credential.");
}

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

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.reauthenticateWithCredential(authCredential);
} catch (error) {
    print("Error reauthenticating credential.");
}

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

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

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

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

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

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

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

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

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

لتسجيل خروج مستخدم، اتّبِع الخطوات التالية:signOut()

await FirebaseAuth.instance.signOut();