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

في حال الترقية إلى Firebase Authentication with Identity Platform، يمكنك إضافة مصادقة متعدّدة العوامل للرسائل القصيرة SMS. إلى تطبيق الويب.

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

قبل البدء

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

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

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

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

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

  1. في Google Cloud Console، اختَر المستأجر الذي تريد العمل معه.

  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 يدويًا. حزمة SDK للعميل ينشئ الكائن RecaptchaVerifier أي إجراءات ضرورية ويضبطها تلقائيًا. مفاتيح العميل وأسراره.

استخدام خدمة 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:

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.
      })
    

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

  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.
    } ...
  });

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

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