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

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

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

قبل البدء

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

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

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

استخدام ميزة "الوصول المتعدّد للمستأجرين"

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

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

  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) الخاصة بالعميل ينشئ ويضبط تلقائيًا أي مفاتيح وأسرار ضرورية للعميل.

استخدام invisible reCAPTCHA

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

Web

import { RecaptchaVerifier, getAuth } from "firebase/auth";

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

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, getAuth } from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier(
    getAuth(),
    "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.
        // ...
      }
    }
);

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 هذه المنطق باستخدام طريقة verify، لذلك لا تحتاج إلى التعامل مع المتغيّر grecaptcha مباشرةً.

تسجيل عامل مصادقة ثانٍ

لتسجيل عامل ثانوي جديد لمستخدم، اتّبِع الخطوات التالية:

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

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

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

    Web

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

    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, getAuth
} from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier(getAuth(),
    'recaptcha-container-id', undefined);
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);
});

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

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

لتسجيل دخول مستخدم باستخدام ميزة التحقّق بخطوتين عبر الرسائل القصيرة، اتّبِع الخطوات التالية:

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

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

    Web

    import { getAuth, signInWithEmailAndPassword, 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, getAuth } from "firebase/auth";
    
    recaptchaVerifier = new RecaptchaVerifier(getAuth(),
        'recaptcha-container-id', undefined);
    

    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(getAuth(),
    'recaptcha-container-id', undefined);

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

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

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