احراز هویت چند عاملی TOTP را به برنامه اندروید خود اضافه کنید

اگر به Firebase Authentication with Identity Platform ارتقا داده‌اید، می‌توانید احراز هویت چند عاملی (MFA) با رمز عبور یکبار مصرف (TOTP) مبتنی بر زمان را به برنامه خود اضافه کنید.

Firebase Authentication with Identity Platform به شما امکان می‌دهد از TOTP به عنوان یک عامل اضافی برای MFA استفاده کنید. وقتی این ویژگی را فعال می‌کنید، کاربرانی که سعی در ورود به برنامه شما دارند، درخواستی برای TOTP مشاهده می‌کنند. برای تولید آن، باید از یک برنامه تأییدکننده هویت که قادر به تولید کدهای TOTP معتبر است، مانند Google Authenticator ، استفاده کنند.

قبل از اینکه شروع کنی

  1. حداقل یک ارائه‌دهنده که از MFA پشتیبانی می‌کند را فعال کنید. توجه داشته باشید که همه ارائه‌دهندگان به جز موارد زیر از MFA پشتیبانی می‌کنند:

    • احراز هویت تلفن
    • نویسنده ناشناس
    • توکن‌های احراز هویت سفارشی
    • مرکز بازی اپل
  2. مطمئن شوید که برنامه شما آدرس‌های ایمیل کاربر را تأیید می‌کند. احراز هویت چندعاملی (MFA) نیاز به تأیید ایمیل دارد. این امر مانع از آن می‌شود که افراد مخرب با آدرس ایمیلی که متعلق به آنها نیست، در یک سرویس ثبت‌نام کنند و سپس با اضافه کردن یک عامل دوم، مالک واقعی آدرس ایمیل را مسدود کنند.

  3. اگر قبلاً این کار را نکرده‌اید، Firebase Android SDK را نصب کنید.

    TOTP MFA فقط در نسخه Android SDK نسخه v22.1.0 و بالاتر پشتیبانی می‌شود.

فعال کردن TOTP MFA

برای فعال کردن TOTP به عنوان عامل دوم، از Admin SDK استفاده کنید یا نقطه پایانی REST پیکربندی پروژه را فراخوانی کنید.

برای استفاده از Admin SDK ، موارد زیر را انجام دهید:

  1. اگر قبلاً این کار را نکرده‌اید، کیت توسعه نرم‌افزار (SDK) مربوط به Firebase Admin Node.js را نصب کنید.

    TOTP MFA فقط در نسخه‌های ۱۱.۶.۰ و بالاتر از کیت توسعه نرم‌افزار Firebase Admin Node.js پشتیبانی می‌شود.

  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 API، دستور زیر را اجرا کنید:

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

قدم بعدی چیست؟