افزودن اصالت‌سنجی چندعاملی TOTP به برنامه وب

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

‫Firebase Authentication with Identity Platform به شما امکان می‌دهد از TOTP به‌عنوان عامل اضافی برای «اصالت‌سنجی چندعاملی» استفاده کنید. وقتی این ویژگی را فعال می‌کنید، کاربرانی که تلاش می‌کنند به سیستم برنامه‌تان وارد شوند، درخواست TOTP را می‌بینند. برای تولید آن، باید از برنامه اصالت‌سنجی‌ای استفاده کنند که بتواند کدهای TOTP معتبر تولید کند، مثل Google Authenticator.

قبل از شروع

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

    • تأیید هویت تلفنی
    • احراز هویت ناشناس
    • کدهای اصالت‌سنجی سفارشی
    • مرکز بازی Apple
  2. مطمئن شوید که برنامه‌تان نشانی‌های ایمیل کاربر را درستی‌سنجی می‌کند. «احراز هویت چندعاملی» به درستی‌سنجی ایمیل نیاز دارد. این کار از ثبت‌نام عاملان مخرب برای سرویس با نشانی ایمیلی که متعلق به آن‌ها نیست جلوگیری می‌کند و سپس با افزودن عامل دوم، مالک واقعی نشانی ایمیل را از دسترسی به آن محروم می‌کند.

  3. اگر قبلاً این کار را نکرده‌اید، کیت توسعه نرم‌افزار جاوا اسکریپت Firebase را نصب کنید.

    «احراز هویت چندعاملی مبتنی بر زمان» فقط در «کیت توسعه نرم‌افزار وب» واحد، نسخه‌های v9.19.1 و بالاتر پشتیبانی می‌شود.

فعال کردن «احراز هویت چندعاملی مبتنی بر زمان»

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

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

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

    «احراز هویت چندعاملی مبتنی بر زمان» فقط در نسخه‌های ۱۱.۶.۰ و بالاتر «کیت توسعه نرم‌افزار 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های پنجره‌های مجاور را نیز بپذیرد.

برای فعال کردن «احراز هویت چندعاملی مبتنی بر زمان» بااستفاده از 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 را پیکربندی کنید تا TOTPهای پنجره‌های مجاور را نیز بپذیرد.

انتخاب الگوی ثبت

می‌توانید انتخاب کنید که آیا برنامه شما به اصالت‌سنجی چندعاملی نیاز دارد یا نه، و چگونه و چه زمانی کاربران خود را ثبت کنید. برخی‌از الگوهای رایج عبارت‌اند از:

  • عامل دوم کاربر را به‌عنوان بخشی از ثبت‌نام ثبت کنید. اگر برنامه شما برای همه کاربران به اصالت‌سنجی چندعاملی نیاز دارد، از این روش استفاده کنید.

  • گزینه‌ای قابل‌رد کردن برای ثبت عامل دوم درطول ثبت‌نام ارائه دهید. اگر می‌خواهید اصالت‌سنجی چندعاملی را در برنامه‌تان تشویق کنید اما آن را الزامی نکنید، می‌توانید از این رویکرد استفاده کنید.

  • امکان افزودن عامل دوم از صفحه مدیریت حساب یا نمایه کاربر، به‌جای صفحه ثبت‌نام، را فراهم کنید. این کار اصطکاک درطول فرایند ثبت‌نام را به حداقل می‌رساند و درعین‌حال، اصالت‌سنجی چندعاملی را برای کاربران حساس به امنیت دردسترس قرار می‌دهد.

  • وقتی کاربر بخواهد به ویژگی‌هایی با الزامات امنیتی بیشتر دسترسی پیدا کند، به‌تدریج افزودن عامل دوم را الزامی کنید.

ثبت‌نام کاربران در «احراز هویت چندعاملی مبتنی بر زمان»

پس‌از فعال کردن «احراز هویت چندعاملی مبتنی بر زمان» به‌عنوان عامل دوم برای برنامه‌تان، منطق سمت مشتری را برای ثبت کاربران در «احراز هویت چندعاملی مبتنی بر زمان» پیاده‌سازی کنید:

  1. کلاس‌ها و توابع لازم برای «احراز هویت چند مرحله‌ای» را وارد کنید:

    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. رمز را به کاربر نشان دهید و از او بخواهید آن را در برنامه اصالت‌سنج وارد کند.

    با بسیاری از برنامه‌های اصالت‌سنجی، کاربران می‌توانند با اسکن کردن رمزینه پاسخ‌سریعی که نشان‌دهنده نشانی وب کلید سازگار با «اصالت‌سنج Google» است، به‌سرعت رمزهای TOTP جدید اضافه کنند. برای تولید رمزینه پاسخ‌سریع برای این هدف، نشانی وب را با 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. از کاربر بخواهید «رمز یک‌بار مصرف مبتنی بر زمان» نمایش‌داده‌شده در برنامه اصالت‌سنجی‌اش را تایپ کند و از آن برای تکمیل ثبت‌نام «درستی‌سنجی چندعاملی» استفاده کند:

    // 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، از کد زیر استفاده کنید:

  1. کلاس‌ها و توابع لازم برای «احراز هویت چند مرحله‌ای» را وارد کنید:

    import {
        getAuth,
        getMultiFactorResolver,
        TotpMultiFactorGenerator,
    } from "firebase/auth";
    
  2. یکی از روش‌های signInWith را مثل زمانی که از «احراز هویت چند مرحله‌ای» استفاده نمی‌کردید فراخوانی کنید. (برای مثال، signInWithEmailAndPassword().) اگر روش خطای auth/multi-factor-auth-required ایجاد می‌کند، جریان «احراز هویت چندعاملی» برنامه‌تان را شروع کنید.

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

خارج شدن از «احراز هویت چندعاملی مبتنی بر زمان»

این بخش نحوه مدیریت کاربر را درصورت لغو ثبت‌نام از «احراز هویت چندعاملی مبتنی بر زمان» توضیح می‌دهد.

اگر کاربری برای چندین گزینه «احراز هویت چندعاملی» ثبت‌نام کرده باشد و از جدیدترین گزینه فعال‌شده لغو ثبت‌نام کند، 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
        );
    }
}

مرحله بعدی چیست