إضافة مصادقة متعدّدة العوامل إلى تطبيق الويب

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

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

قبل البدء

  1. فعِّل موفّر خدمة واحدًا على الأقل يتيح المصادقة المتعدّدة العوامل. يتيح كل مقدّم خدمة المصادقة المتعدّدة القنوات (MFA)، باستثناء مصادقة الهاتف، والمصادقة المجهولة، وApple Game Center.

  2. يجب تفعيل المناطق التي تريد استخدام مصادقة الرسائل القصيرة SMS فيها. يستخدم Firebase سياسة منطقة للحظر الكامل للرسائل القصيرة، والتي تساعد على إنشاء مشاريعك بحالة أكثر أمانًا تلقائيًا.

  3. تأكَّد من أنّ تطبيقك يتحقّق من عناوين البريد الإلكتروني للمستخدمين. تتطلب MFA إثبات ملكية عنوان البريد الإلكتروني. ويؤدي ذلك إلى منع الجهات الضارّة من التسجيل في خدمة باستخدام عنوان بريد إلكتروني لا تملكه، ثم حظر المالك الحقيقي عن طريق إضافة عامل ثانٍ.

استخدام الحيز المتعدد

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

  1. في وحدة تحكّم Google Cloud Platform، اختَر المستأجر الذي تريد العمل معه.

  2. في الرمز، اضبط الحقل tenantId على المثيل Auth على معرّف المستأجر. على سبيل المثال:

    Web

    import { getAuth } from "firebase/auth";
    
    const auth = getAuth(app);
    auth.tenantId = "myTenantId1";
    

    Web

    firebase.auth().tenantId = 'myTenantId1';
    

تفعيل المصادقة المتعدّدة العوامل

  1. افتح صفحة المصادقة > طريقة تسجيل الدخول في وحدة تحكّم Firebase.

  2. في القسم الإعدادات المتقدّمة، فعِّل المصادقة المتعدّدة العوامل للرسائل القصيرة.

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

  3. إذا لم تكن قد فوّضت نطاق تطبيقك من قبل، يمكنك إضافته إلى قائمة السماح في صفحة المصادقة > الإعدادات بوحدة تحكُّم Firebase.

اختيار نمط التسجيل

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

  • سجِّل العامل الثاني للمستخدم كجزء من التسجيل. استخدِم هذه الطريقة إذا كان تطبيقك يتطلّب مصادقة متعدّدة العوامل لجميع المستخدمين.

  • عليك توفير خيار قابل للتخطّي لتسجيل عامل ثانٍ أثناء التسجيل. التطبيقات التي ترغب في تشجيع إجراء مصادقة متعددة العوامل لها دون الحاجة إليها قد تفضل هذه الطريقة.

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

  • يمكنك طلب إضافة عامل ثانٍ بشكل تدريجي عندما يريد المستخدم الوصول إلى ميزات ذات متطلبات أمان متزايدة.

إعداد أداة التحقّق من reCAPTCHA

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

لا تحتاج إلى إعداد برنامج reCAPTCHA يدويًا، لأنّ كائن RecaptchaVerifier في حزمة تطوير البرامج (SDK) للعميل ينشئ تلقائيًا أي مفاتيح وأسرار للعميل الضرورية ويضبطها.

استخدام خدمة reCAPTCHA غير مرئية

يتيح الكائن RecaptchaVerifier reCAPTCHA غير مرئي، والذي يتيح غالبًا التحقق من المستخدم بدون الحاجة إلى أي تفاعل. لاستخدام reCAPTCHA غير مرئي، يمكنك إنشاء RecaptchaVerifier مع ضبط المعلَمة size على invisible، وتحديد معرّف عنصر واجهة المستخدم الذي يبدأ التسجيل المتعدّد العوامل:

Web

import { RecaptchaVerifier } from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier("sign-in-button", {
    "size": "invisible",
    "callback": function(response) {
        // reCAPTCHA solved, you can proceed with
        // phoneAuthProvider.verifyPhoneNumber(...).
        onSolvedRecaptcha();
    }
}, auth);

Web

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
'size': 'invisible',
'callback': function(response) {
  // reCAPTCHA solved, you can proceed with phoneAuthProvider.verifyPhoneNumber(...).
  onSolvedRecaptcha();
}
});

استخدام تطبيق reCAPTCHA المصغّر

لاستخدام تطبيق مصغّر يعرض reCAPTCHA، أنشِئ عنصر HTML يحتوي على التطبيق المصغّر، ثم أنشِئ كائن RecaptchaVerifier برقم تعريف حاوية واجهة المستخدم. يمكنك أيضًا اختياريًا ضبط عمليات الاستدعاء التي يتم استدعاؤها عند حلّ اختبار reCAPTCHA أو انتهاء صلاحيته:

Web

import { RecaptchaVerifier } from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier(
    "recaptcha-container",

    // Optional reCAPTCHA parameters.
    {
      "size": "normal",
      "callback": function(response) {
        // reCAPTCHA solved, you can proceed with
        // phoneAuthProvider.verifyPhoneNumber(...).
        onSolvedRecaptcha();
      },
      "expired-callback": function() {
        // Response expired. Ask user to solve reCAPTCHA again.
        // ...
      }
    }, auth
);

Web

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier(
  'recaptcha-container',
  // Optional reCAPTCHA parameters.
  {
    'size': 'normal',
    'callback': function(response) {
      // reCAPTCHA solved, you can proceed with phoneAuthProvider.verifyPhoneNumber(...).
      // ...
      onSolvedRecaptcha();
    },
    'expired-callback': function() {
      // Response expired. Ask user to solve reCAPTCHA again.
      // ...
    }
  });

عرض reCAPTCHA مسبقًا

يمكنك اختياريًا عرض اختبار reCAPTCHA مسبقًا قبل بدء التسجيل الثنائي:

Web

recaptchaVerifier.render()
    .then(function (widgetId) {
        window.recaptchaWidgetId = widgetId;
    });

Web

recaptchaVerifier.render()
  .then(function(widgetId) {
    window.recaptchaWidgetId = widgetId;
  });

بعد حلّ render()، ستحصل على رقم تعريف التطبيق المصغّر الخاص بـ reCAPTCHA، والذي يمكنك استخدامه لإجراء طلبات من خلال reCAPTCHA API:

var recaptchaResponse = grecaptcha.getResponse(window.recaptchaWidgetId);

يستخرج reCAPTCHAVerifier هذا المنطق باستخدام طريقة التحقق، وبذلك لا تحتاج إلى التعامل مع متغير grecaptcha بشكل مباشر.

تسجيل عامل ثانٍ

لتسجيل عامل ثانوي جديد لمستخدم:

  1. أعِد مصادقة المستخدم.

  2. اطلب من المستخدم إدخال رقم هاتفه.

  3. هيئ أداة التحقّق reCAPTCHA على النحو الموضّح في القسم السابق. يمكنك تخطّي هذه الخطوة إذا سبق أن تم ضبط مثيل reCAPTCHAVerifier:

    Web

    import { RecaptchaVerifier } from "firebase/auth";
    
    const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
    

    Web

    var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
    
  4. الحصول على جلسة متعددة العوامل للمستخدم:

    Web

    import { multiFactor } from "firebase/auth";
    
    multiFactor(user).getSession().then(function (multiFactorSession) {
        // ...
    });
    

    Web

    user.multiFactor.getSession().then(function(multiFactorSession) {
      // ...
    })
    
  5. يمكنك إعداد كائن PhoneInfoOptions باستخدام رقم هاتف المستخدم وجلسة متعددة العوامل:

    Web

    // Specify the phone number and pass the MFA session.
    const phoneInfoOptions = {
      phoneNumber: phoneNumber,
      session: multiFactorSession
    };
    

    Web

    // Specify the phone number and pass the MFA session.
    var phoneInfoOptions = {
      phoneNumber: phoneNumber,
      session: multiFactorSession
    };
    
  6. إرسال رسالة تحقق إلى هاتف المستخدم:

    Web

    import { PhoneAuthProvider } from "firebase/auth";
    
    const phoneAuthProvider = new PhoneAuthProvider(auth);
    phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
        .then(function (verificationId) {
            // verificationId will be needed to complete enrollment.
        });
    

    Web

    var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
    // Send SMS verification code.
    return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
      .then(function(verificationId) {
        // verificationId will be needed for enrollment completion.
      })
    

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

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

    Web

    recaptchaVerifier.clear();
    

    Web

    recaptchaVerifier.clear();
    
  8. بعد إرسال رمز SMS، اطلب من المستخدم إثبات صحة الرمز باتّباع الخطوات التالية:

    Web

    // Ask user for the verification code. Then:
    const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
    

    Web

    // Ask user for the verification code. Then:
    var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
    
  9. إعداد كائن MultiFactorAssertion باستخدام PhoneAuthCredential:

    Web

    import { PhoneMultiFactorGenerator } from "firebase/auth";
    
    const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
    

    Web

    var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
    
  10. أكمِل عملية التسجيل. يمكنك اختياريًا تحديد اسم معروض للعامل الثاني. ويكون ذلك مفيدًا للمستخدمين الذين لديهم عدة عوامل ثانية، لأنّ رقم الهاتف يكون مخفيًا أثناء مسار المصادقة (على سبيل المثال، +1******1234).

    Web

    // Complete enrollment. This will update the underlying tokens
    // and trigger ID token change listener.
    multiFactor(user).enroll(multiFactorAssertion, "My personal phone number");
    

    Web

    // Complete enrollment. This will update the underlying tokens
    // and trigger ID token change listener.
    user.multiFactor.enroll(multiFactorAssertion, 'My personal phone number');
    

يوضح الرمز أدناه مثالاً كاملاً لتسجيل عامل ثانٍ:

Web

import {
    multiFactor, PhoneAuthProvider, PhoneMultiFactorGenerator,
    RecaptchaVerifier
} from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
multiFactor(user).getSession()
    .then(function (multiFactorSession) {
        // Specify the phone number and pass the MFA session.
        const phoneInfoOptions = {
            phoneNumber: phoneNumber,
            session: multiFactorSession
        };

        const phoneAuthProvider = new PhoneAuthProvider(auth);

        // Send SMS verification code.
        return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier);
    }).then(function (verificationId) {
        // Ask user for the verification code. Then:
        const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
        const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);

        // Complete enrollment.
        return multiFactor(user).enroll(multiFactorAssertion, mfaDisplayName);
    });

Web

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
user.multiFactor.getSession().then(function(multiFactorSession) {
  // Specify the phone number and pass the MFA session.
  var phoneInfoOptions = {
    phoneNumber: phoneNumber,
    session: multiFactorSession
  };
  var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
  // Send SMS verification code.
  return phoneAuthProvider.verifyPhoneNumber(
      phoneInfoOptions, recaptchaVerifier);
})
.then(function(verificationId) {
  // Ask user for the verification code.
  var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
  var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
  // Complete enrollment.
  return user.multiFactor.enroll(multiFactorAssertion, mfaDisplayName);
});

تهانينا لقد سجّلت بنجاح عامل مصادقة ثانٍ لمستخدم.

تسجيل دخول المستخدمين بعامل ثانٍ

لتسجيل دخول مستخدم باستخدام ميزة إثبات الهوية عبر الرسائل القصيرة SMS:

  1. سجِّل دخول المستخدم باستخدام العامل الأول، ثم ستظهر خطأ auth/multi-factor-auth-required. يحتوي هذا الخطأ على أداة حل وتلميحات عن العوامل الثانية المسجَّلة وجلسة أساسية تثبت مصادقة المستخدم بنجاح باستخدام العامل الأول.

    على سبيل المثال، إذا كان العامل الأول للمستخدم هو البريد الإلكتروني وكلمة المرور:

    Web

    import { getAuth, getMultiFactorResolver} from "firebase/auth";
    
    const auth = getAuth();
    signInWithEmailAndPassword(auth, email, password)
        .then(function (userCredential) {
            // User successfully signed in and is not enrolled with a second factor.
        })
        .catch(function (error) {
            if (error.code == 'auth/multi-factor-auth-required') {
                // The user is a multi-factor user. Second factor challenge is required.
                resolver = getMultiFactorResolver(auth, error);
                // ...
            } else if (error.code == 'auth/wrong-password') {
                // Handle other errors such as wrong password.
            }
    });
    

    Web

    firebase.auth().signInWithEmailAndPassword(email, password)
      .then(function(userCredential) {
        // User successfully signed in and is not enrolled with a second factor.
      })
      .catch(function(error) {
        if (error.code == 'auth/multi-factor-auth-required') {
          // The user is a multi-factor user. Second factor challenge is required.
          resolver = error.resolver;
          // ...
        } else if (error.code == 'auth/wrong-password') {
          // Handle other errors such as wrong password.
        } ...
      });
    

    إذا كان العامل الأول للمستخدم هو مقدِّم خدمة موحّد، مثل OAuth أو SAML أو OIDC، يمكنك رصد الخطأ بعد طلب signInWithPopup() أو signInWithRedirect().

  2. إذا كان المستخدم لديه عدة عوامل ثانوية مسجلة، فاسأله عن العامل الذي يجب استخدامه:

    Web

    // Ask user which second factor to use.
    // You can get the masked phone number via resolver.hints[selectedIndex].phoneNumber
    // You can get the display name via resolver.hints[selectedIndex].displayName
    
    if (resolver.hints[selectedIndex].factorId ===
        PhoneMultiFactorGenerator.FACTOR_ID) {
        // User selected a phone second factor.
        // ...
    } else if (resolver.hints[selectedIndex].factorId ===
               TotpMultiFactorGenerator.FACTOR_ID) {
        // User selected a TOTP second factor.
        // ...
    } else {
        // Unsupported second factor.
    }
    

    Web

    // Ask user which second factor to use.
    // You can get the masked phone number via resolver.hints[selectedIndex].phoneNumber
    // You can get the display name via resolver.hints[selectedIndex].displayName
    if (resolver.hints[selectedIndex].factorId === firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
      // User selected a phone second factor.
      // ...
    } else if (resolver.hints[selectedIndex].factorId === firebase.auth.TotpMultiFactorGenerator.FACTOR_ID) {
      // User selected a TOTP second factor.
      // ...
    } else {
      // Unsupported second factor.
    }
    
  3. هيئ أداة التحقّق reCAPTCHA على النحو الموضّح في القسم السابق. يمكنك تخطّي هذه الخطوة إذا سبق أن تم ضبط مثيل reCAPTCHAVerifier:

    Web

    import { RecaptchaVerifier } from "firebase/auth";
    
    recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
    

    Web

    var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
    
  4. يمكنك إعداد كائن PhoneInfoOptions باستخدام رقم هاتف المستخدم والجلسة المتعددة العوامل. يتم تضمين هذه القيم في الكائن resolver الذي تم تمريره إلى الخطأ auth/multi-factor-auth-required:

    Web

    const phoneInfoOptions = {
        multiFactorHint: resolver.hints[selectedIndex],
        session: resolver.session
    };
    

    Web

    var phoneInfoOptions = {
      multiFactorHint: resolver.hints[selectedIndex],
      session: resolver.session
    };
    
  5. إرسال رسالة تحقق إلى هاتف المستخدم:

    Web

    // Send SMS verification code.
    const phoneAuthProvider = new PhoneAuthProvider(auth);
    phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
        .then(function (verificationId) {
            // verificationId will be needed for sign-in completion.
        });
    

    Web

    var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
    // Send SMS verification code.
    return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
      .then(function(verificationId) {
        // verificationId will be needed for sign-in completion.
      })
    
  6. إذا تعذّر الطلب، أعِد ضبط reCAPTCHA، ثم كرِّر الخطوة السابقة كي يتمكّن المستخدم من المحاولة مرة أخرى:

    Web

    recaptchaVerifier.clear();
    

    Web

    recaptchaVerifier.clear();
    
  7. بعد إرسال رمز SMS، اطلب من المستخدم إثبات صحة الرمز باتّباع الخطوات التالية:

    Web

    const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
    

    Web

    // Ask user for the verification code. Then:
    var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
    
  8. إعداد كائن MultiFactorAssertion باستخدام PhoneAuthCredential:

    Web

    const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
    

    Web

    var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
    
  9. يمكنك الاتصال بالرقم resolver.resolveSignIn() لإكمال المصادقة الثانوية. يمكنك بعد ذلك الوصول إلى النتيجة الأصلية لتسجيل الدخول، والتي تتضمن بيانات اعتماد المصادقة والبيانات الخاصة بمزود الخدمة القياسي:

    Web

    // Complete sign-in. This will also trigger the Auth state listeners.
    resolver.resolveSignIn(multiFactorAssertion)
        .then(function (userCredential) {
            // userCredential will also contain the user, additionalUserInfo, optional
            // credential (null for email/password) associated with the first factor sign-in.
    
            // For example, if the user signed in with Google as a first factor,
            // userCredential.additionalUserInfo will contain data related to Google
            // provider that the user signed in with.
            // - user.credential contains the Google OAuth credential.
            // - user.credential.accessToken contains the Google OAuth access token.
            // - user.credential.idToken contains the Google OAuth ID token.
        });
    

    Web

    // Complete sign-in. This will also trigger the Auth state listeners.
    resolver.resolveSignIn(multiFactorAssertion)
      .then(function(userCredential) {
        // userCredential will also contain the user, additionalUserInfo, optional
        // credential (null for email/password) associated with the first factor sign-in.
        // For example, if the user signed in with Google as a first factor,
        // userCredential.additionalUserInfo will contain data related to Google provider that
        // the user signed in with.
        // user.credential contains the Google OAuth credential.
        // user.credential.accessToken contains the Google OAuth access token.
        // user.credential.idToken contains the Google OAuth ID token.
      });
    

يوضح الرمز أدناه مثالاً كاملاً لتسجيل دخول مستخدم متعدد العوامل:

Web

import {
    getAuth,
    getMultiFactorResolver,
    PhoneAuthProvider,
    PhoneMultiFactorGenerator,
    RecaptchaVerifier,
    signInWithEmailAndPassword
} from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);

const auth = getAuth();
signInWithEmailAndPassword(auth, email, password)
    .then(function (userCredential) {
        // User is not enrolled with a second factor and is successfully
        // signed in.
        // ...
    })
    .catch(function (error) {
        if (error.code == 'auth/multi-factor-auth-required') {
            const resolver = getMultiFactorResolver(auth, error);
            // Ask user which second factor to use.
            if (resolver.hints[selectedIndex].factorId ===
                PhoneMultiFactorGenerator.FACTOR_ID) {
                const phoneInfoOptions = {
                    multiFactorHint: resolver.hints[selectedIndex],
                    session: resolver.session
                };
                const phoneAuthProvider = new PhoneAuthProvider(auth);
                // Send SMS verification code
                return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
                    .then(function (verificationId) {
                        // Ask user for the SMS verification code. Then:
                        const cred = PhoneAuthProvider.credential(
                            verificationId, verificationCode);
                        const multiFactorAssertion =
                            PhoneMultiFactorGenerator.assertion(cred);
                        // Complete sign-in.
                        return resolver.resolveSignIn(multiFactorAssertion)
                    })
                    .then(function (userCredential) {
                        // User successfully signed in with the second factor phone number.
                    });
            } else if (resolver.hints[selectedIndex].factorId ===
                       TotpMultiFactorGenerator.FACTOR_ID) {
                // Handle TOTP MFA.
                // ...
            } else {
                // Unsupported second factor.
            }
        } else if (error.code == 'auth/wrong-password') {
            // Handle other errors such as wrong password.
        }
    });

Web

var resolver;
firebase.auth().signInWithEmailAndPassword(email, password)
  .then(function(userCredential) {
    // User is not enrolled with a second factor and is successfully signed in.
    // ...
  })
  .catch(function(error) {
    if (error.code == 'auth/multi-factor-auth-required') {
      resolver = error.resolver;
      // Ask user which second factor to use.
      if (resolver.hints[selectedIndex].factorId ===
          firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
        var phoneInfoOptions = {
          multiFactorHint: resolver.hints[selectedIndex],
          session: resolver.session
        };
        var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
        // Send SMS verification code
        return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
          .then(function(verificationId) {
            // Ask user for the SMS verification code.
            var cred = firebase.auth.PhoneAuthProvider.credential(
                verificationId, verificationCode);
            var multiFactorAssertion =
                firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
            // Complete sign-in.
            return resolver.resolveSignIn(multiFactorAssertion)
          })
          .then(function(userCredential) {
            // User successfully signed in with the second factor phone number.
          });
      } else if (resolver.hints[selectedIndex].factorId ===
        firebase.auth.TotpMultiFactorGenerator.FACTOR_ID) {
        // Handle TOTP MFA.
        // ...
      } else {
        // Unsupported second factor.
      }
    } else if (error.code == 'auth/wrong-password') {
      // Handle other errors such as wrong password.
    } ...
  });

تهانينا لقد نجحت في تسجيل دخول مستخدم باستخدام المصادقة متعددة العوامل.

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