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

إذا أجريت الترقية إلى مصادقة Firebase باستخدام "نظام التحقق من الهوية"، يمكنك إضافة كلمة مرور صالحة لمرة واحدة (TOTP) إلى تطبيقك لمصادقة Firebase.

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

قبل البدء

  1. يجب تفعيل مقدِّم خدمة واحد على الأقل يتوافق مع المواقع المصممة بغرض الإعلانات (MFA). يُرجى العِلم أنّ جميع مقدّمي الخدمات باستثناء الجهات التالية التي تتوافق مع المواقع المصممة بغرض الإعلانات (MFA):

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

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

    لا يتوافق TOTP MFA إلا على الإصدار 22.1.0 من حزمة تطوير البرامج (SDK) لنظام التشغيل Android والإصدارات الأحدث.

تفعيل TOTP MFA

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

لاستخدام حزمة SDK للمشرف، يمكنك تنفيذ ما يلي:

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

    لا يتوافق TOTP MFA إلّا مع الإصدار 11.6.0 والإصدارات الأحدث من حزمة تطوير البرامج (SDK) لمشرف 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) عن طريق التأكّد من أنّه عندما ينشئ طرفان (المثبت والمدقق) كلمات المرور لمرة واحدة (OTP) خلال الفترة الزمنية نفسها (التي تبلغ مدتها عادةً 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) عن طريق التأكّد من أنّه عندما ينشئ طرفان (المثبت والمدقق) كلمات المرور لمرة واحدة (OTP) خلال الفترة الزمنية نفسها (التي تبلغ مدتها عادةً 30 ثانية)، ينشئان كلمة المرور نفسها. ومع ذلك، لاستيعاب اختلاف الساعة بين الأطراف ووقت الاستجابة البشري، يمكنك ضبط خدمة TOTP أيضًا لقبول منصّات TOTP من النوافذ المجاورة.

اختيار نقش التسجيل

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

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

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

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

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

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

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

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

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

    // Generate a TOTP secret.
    Firebase.auth.currentUser.multiFactor.session
        .addOnSuccessListener { multiFactorSession ->
            TotpMultiFactorGenerator.generateSecret(multiFactorSession)
                .addOnSuccessListener { totpSecret ->
                    // Display the secret to the user and prompt them to
                    // enter it into their authenticator app. (See the next
                    // step.)
                }
        }
    
  3. اعرض المفتاح السرّي للمستخدم واطلب منه إدخاله في تطبيق المصادقة:

    // Display this key:
    val secret = totpSecret.sharedSecretKey
    

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

    val qrCodeUri = totpSecret.generateQrCodeUrl(
        currentUser.email ?: "default account",
        "Your App Name")
    totpSecret.openInOtpApp(qrCodeUri)
    

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

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

    // Ask the user for a verification code from the authenticator app.
    val verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    val multiFactorAssertion = TotpMultiFactorGenerator
        .getAssertionForEnrollment(totpSecret, verificationCode)
    Firebase.auth.currentUser.multiFactor.enroll(multiFactorAssertion, "TOTP")
        .addOnSuccessListener {
            // Enrollment complete.
        }
    

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

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

  1. يمكنك استدعاء إحدى الطريقتين (signInWith) كما تفعل في حال عدم استخدام المواقع المصممة بغرض الإعلانات (MFA). (على سبيل المثال، signInWithEmailAndPassword().) إذا عرضت الطريقة الرمز FirebaseAuthMultiFactorException، يمكنك بدء مسار MFA لتطبيقك.

    Firebase.auth.signInWithEmailAndPassword(email, password)
        .addOnSuccessListener { result ->
            // 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.)
    
            // ...
        }
        .addOnFailureListener { exception ->
            when (exception) {
                is FirebaseAuthMultiFactorException -> {
                    // Initiate your second factor sign-in flow. (See next step.)
                    // ...
                }
            }
        }
    
  2. يجب أن يحث تدفق MFA في تطبيقك أولاً المستخدم على اختيار العامل الثاني الذي يريد استخدامه. يمكنك الحصول على قائمة بالعوامل الثانية المتوافقة من خلال فحص السمة hints لمثيل MultiFactorResolver:

    val enrolledFactors = exception.resolver.hints.map { it.displayName }
    
  3. إذا اختار المستخدم استخدام TOTP، اطلب منه كتابة تفاصيل TOTP المعروض على تطبيق المصادقة واستخدامها لتسجيل الدخول:

    when (exception.resolver.hints[selectedIndex].factorId) {
        TotpMultiFactorGenerator.FACTOR_ID -> {
            val otpFromAuthenticator = // OTP typed by the user.
            val assertion = TotpMultiFactorGenerator.getAssertionForSignIn(
                exception.resolver.hints[selectedIndex].uid,
                otpFromAuthenticator
            )
            exception.resolver.resolveSignIn(assertion)
                .addOnSuccessListener { result ->
                    // Successfully signed in!
                }
                .addOnFailureListener { resolveError ->
                    // Invalid or expired OTP.
                }
        }
        PhoneMultiFactorGenerator.FACTOR_ID -> {
            // Handle SMS second factor.
        }
    }
    

إلغاء التسجيل في TOTP MFA

يصف هذا القسم كيفية التعامل مع إلغاء تسجيل مستخدم في TOTP MFA.

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

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

Firebase.auth.currentUser.multiFactor.unenroll(mfaEnrollmentId)
    .addOnSuccessListener {
        // Second factor unenrolled.
    }
    .addOnFailureListener { exception ->
        when (exception) {
            is FirebaseAuthInvalidUserException -> {
                // Second factor unenrolled. 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.
                val credential = EmailAuthProvider.getCredential(email, password)
                currentUser.reauthenticate(credential)
                    .addOnSuccessListener { 
                        // Success!
                    }
                    .addOnFailureListener { 
                        // Bad email address and password combination.
                    }
            }
        }
    }

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