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

في حال الترقية إلى "مصادقة Firebase" باستخدام "منصة الهوية"، يمكنك إضافة مصادقة متعدّدة العوامل (MFA) مستندة إلى الوقت إلى تطبيقك باستخدام كلمة المرور لمرة واحدة.

تتيح لك "مصادقة Firebase" باستخدام "نظام إدارة الهوية" استخدام دالة TOTP كعامل إضافي لـ MFA. عند تفعيل هذه الميزة، سيظهر للمستخدمين الذين يحاولون تسجيل الدخول إلى تطبيقك طلبًا للحصول على TOTP. لإنشائه، يجب استخدام تطبيق مصادقة قادر على إنشاء رموز TOTP صالحة، مثل Google Authenticator.

قبل البدء

  1. عليك تفعيل مقدِّم خدمة واحد على الأقل يتيح MFA. يُرجى العلم أنّ جميع مقدّمي الخدمات باستثناء ما يلي يتيحون استخدام "MFA":

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

  3. ثبِّت حزمة تطوير البرامج (SDK) لJavaScript JavaScript لمنصة Firebase إذا لم يسبق لك إجراء ذلك.

    لا يتوفّر نموذج TOTP MFA إلا على حزمة تطوير البرامج (SDK) للويب النموذجية على الإصدار v9.19.1 والإصدارات الأحدث.

تفعيل TOTP MFA

لتفعيل بروتوكول TOTP كعامل ثانٍ، استخدِم حزمة SDK للمشرف أو اطلب نقطة نهاية REST لإعداد المشروع.

لاستخدام SDK للمشرف، نفِّذ ما يلي:

  1. ثبِّت حزمة تطوير البرامج Node.js SDK لمشرف Firebase إذا لم يسبق لك إجراء ذلك.

    لا يتوفّر TOTP MFA إلا على الإصدار 11.6.0 والإصدارات الأحدث من حزمة SDK Admin Node.js في Firebase.

  2. نفِّذ ما يلي:

    import { getAuth } from 'firebase-admin/auth';
    
    getAuth().projectConfigManager().updateProjectConfig(
    {
          multiFactorConfig: {
              providerConfigs: [{
                  state: "ENABLED",
                  totpProviderConfig: {
                      adjacentIntervals: {
                          NUM_ADJ_INTERVALS
                      },
                  }
              }]
          }
    })
    

    استبدل ما يلي:

    • NUM_ADJ_INTERVALS: عدد الفواصل الزمنية المتجاورة التي يتم من خلالها قبول روابط TOTP، من صفر إلى عشرة. العدد الافتراضي خمسة.

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

لتفعيل TOTP MFA باستخدام واجهة برمجة تطبيقات REST، شغِّل ما يلي:

curl -X PATCH "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=mfa" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: PROJECT_ID" \
    -d \
    '{
        "mfa": {
          "providerConfigs": [{
            "state": "ENABLED",
            "totpProviderConfig": {
              "adjacentIntervals": "NUM_ADJ_INTERVALS"
            }
          }]
       }
    }'

استبدل ما يلي:

  • PROJECT_ID: رقم تعريف المشروع.
  • NUM_ADJ_INTERVALS: عدد الفواصل الزمنية من صفر إلى عشرة العدد التلقائي هو خمسة.

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

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

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

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

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

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

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

تسجيل مستخدمين في TOTP MFA

بعد تفعيل TOTP MFA كعامل ثانٍ لتطبيقك، نفِّذ المنطق من جهة العميل لتسجيل المستخدمين في TOTP MFA:

  1. استيراد فئات ودوال MFA المطلوبة:

    import {
      multiFactor,
      TotpMultiFactorGenerator,
      TotpSecret,
      getAuth,
    } from "firebase/auth";
    
  2. أعِد مصادقة المستخدم.

  3. إنشاء سر TOTP للمستخدم الذي تمت مصادقته:

    // Generate a TOTP secret.
    const multiFactorSession = await multiFactor(currentUser).getSession();
    const totpSecret = await TotpMultiFactorGenerator.generateSecret(
      multiFactorSession
    );
    
  4. اعرض المفتاح السرّي للمستخدم واطلب منه إدخاله في تطبيق المصادقة الخاص به.

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

    const totpUri = totpSecret.generateQrCodeUrl(
        currentUser.email,
        "Your App's Name"
    );
    await QRExampleLib.toCanvas(totpUri, qrElement);
    

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

    // Also display this key:
    const secret = totpSecret.secretKey;
    

    بعد أن يضيف المستخدم سره إلى تطبيق المصادقة، سيبدأ في إنشاء مفاتيح TOTP.

  5. اطلب من المستخدم كتابة TOTP المعروض في تطبيق المصادقة واستخدامه لإنهاء عملية تسجيل MFA:

    // Ask the user for a verification code from the authenticator app.
    const verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    const multiFactorAssertion = TotpMultiFactorGenerator.assertionForEnrollment(
      totpSecret,
      verificationCode
    );
    await multiFactor(currentUser).enroll(multiFactorAssertion, mfaDisplayName);
    

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

لتسجيل دخول المستخدمين باستخدام TOTP MFA، استخدِم الرمز التالي:

  1. استيراد فئات ودوال MFA المطلوبة:

    import {
        getAuth,
        getMultiFactorResolver,
        TotpMultiFactorGenerator,
    } from "firebase/auth";
    
  2. استدعِ إحدى طرق signInWith كما تفعل في حال لم تكن تستخدِم MFA. (على سبيل المثال، signInWithEmailAndPassword().) إذا عرضت الطريقة الخطأ auth/multi-factor-auth-required، ابدأ مسار MFA في تطبيقك.

    try {
        const userCredential = await signInWithEmailAndPassword(
            getAuth(),
            email,
            password
        );
        // If the user is not enrolled with a second factor and provided valid
        // credentials, sign-in succeeds.
    
        // (If your app requires MFA, this could be considered an error
        // condition, which you would resolve by forcing the user to enroll a
        // second factor.)
    
        // ...
    } catch (error) {
        switch (error.code) {
            case "auth/multi-factor-auth-required":
                // Initiate your second factor sign-in flow. (See next step.)
                // ...
                break;
            case ...:  // Handle other errors, such as wrong passwords.
                break;
        }
    }
    
  3. يجب أن يطلب تدفق MFA في تطبيقك أولاً من المستخدم اختيار العامل الثاني الذي يريد استخدامه. يمكنك الحصول على قائمة بالعوامل الثانية المتوافقة من خلال فحص السمة hints لمثيل MultiFactorResolver:

    const mfaResolver = getMultiFactorResolver(getAuth(), error);
    const enrolledFactors = mfaResolver.hints.map(info => info.displayName);
    
  4. إذا اختار المستخدم استخدام TOTP، اطلب منه كتابة TOTP المعروض على تطبيق المصادقة الخاص به واستخدامه لتسجيل الدخول:

    switch (mfaResolver.hints[selectedIndex].factorId) {
        case TotpMultiFactorGenerator.FACTOR_ID:
            const otpFromAuthenticator = // OTP typed by the user.
            const multiFactorAssertion =
                TotpMultiFactorGenerator.assertionForSignIn(
                    mfaResolver.hints[selectedIndex].uid,
                    otpFromAuthenticator
                );
            try {
                const userCredential = await mfaResolver.resolveSignIn(
                    multiFactorAssertion
                );
                // Successfully signed in!
            } catch (error) {
                // Invalid or expired OTP.
            }
            break;
        case PhoneMultiFactorGenerator.FACTOR_ID:
            // Handle SMS second factor.
            break;
        default:
            // Unsupported second factor?
            break;
    }
    

إلغاء التسجيل من TOTP MFA

يوضِّح هذا القسم كيفية التعامل مع إلغاء تسجيل المستخدم من TOTP MFA.

في حال اشترك المستخدم في عدّة خيارات MFA، وفي حال إلغاء التسجيل من أحدث خيار تم تفعيله، سيتلقّى auth/user-token-expired ويتم تسجيل الخروج. على المستخدم تسجيل الدخول مرة أخرى والتحقُّق من بيانات الاعتماد الحالية، مثل عنوان البريد الإلكتروني وكلمة المرور.

لإلغاء تسجيل المستخدم ومعالجة الخطأ وبدء إعادة المصادقة، استخدِم الرمز التالي:

import {
    EmailAuthProvider,
    TotpMultiFactorGenerator,
    getAuth,
    multiFactor,
    reauthenticateWithCredential,
} from "firebase/auth";

try {
    // Unenroll from TOTP MFA.
    await multiFactor(currentUser).unenroll(mfaEnrollmentId);
} catch  (error) {
    if (error.code === 'auth/user-token-expired') {
        // If the user was signed out, re-authenticate them.

        // For example, if they signed in with a password, prompt them to
        // provide it again, then call `reauthenticateWithCredential()` as shown
        // below.

        const credential = EmailAuthProvider.credential(email, password);
        await reauthenticateWithCredential(
            currentUser,
            credential
        );
    }
}

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