הוסף אימות רב-גורמי TOTP לאפליקציית Android שלך

אם שדרגת ל-Firebase Authentication with Identity Platform, תוכל להוסיף סיסמה חד-פעמית מבוססת-זמן (TOTP) אימות רב-גורמי (MFA) לאפליקציה שלך.

אימות Firebase עם Identity Platform מאפשר לך להשתמש ב-TOTP כגורם נוסף עבור MFA. כאשר אתה מפעיל תכונה זו, משתמשים המנסים להיכנס לאפליקציה שלך רואים בקשה ל-TOTP. כדי ליצור אותו, עליהם להשתמש באפליקציית אימות המסוגלת ליצור קודי TOTP חוקיים, כגון Google Authenticator .

לפני שאתה מתחיל

  1. אפשר לפחות ספק אחד שתומך ב-MFA. שימו לב שכל הספקים מלבד ה-MFA הבאים תומכים ב-MFA:

    • אישור טלפון
    • אישור אנונימי
    • אסימוני אישור מותאמים אישית
    • מרכז המשחקים של אפל
  2. ודא שהאפליקציה שלך מאמתת כתובות דוא"ל של משתמשים. MFA דורש אימות דוא"ל. זה מונע משחקנים זדוניים להירשם לשירות עם כתובת דוא"ל שאינה בבעלותם, ולאחר מכן לנעול את הבעלים האמיתי של כתובת הדוא"ל על ידי הוספת גורם שני.

  3. אם עדיין לא עשית זאת, התקן את Firebase Android SDK .

    TOTP MFA נתמך רק בגרסת Android SDK v22.1.0 ומעלה.

אפשר TOTP MFA

כדי להפעיל TOTP כגורם שני, השתמש ב-Admin SDK או התקשר לנקודת הקצה REST של תצורת הפרויקט.

כדי להשתמש ב-Admin SDK, בצע את הפעולות הבאות:

  1. אם עדיין לא עשית זאת, התקן את Firebase Admin Node.js SDK .

    TOTP MFA נתמך רק ב-Firebase Admin Node.js SDK בגרסאות 11.6.0 ומעלה.

  2. הפעל את הפעולות הבאות:

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

    החלף את הדברים הבאים:

    • NUM_ADJ_INTERVALS : מספר מרווחי חלון הזמן הסמוכים שמהם ניתן לקבל TOTPs, מאפס עד עשרה. ברירת המחדל היא חמש.

      TOTPs פועלים על ידי הבטחה שכאשר שני צדדים (המוכיח והמאמת) יוצרים OTPs בתוך אותו חלון זמן (בדרך כלל באורך 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 : מספר מרווחי חלון הזמן, מאפס עד עשרה. ברירת המחדל היא חמש.

    TOTPs פועלים על ידי הבטחה שכאשר שני צדדים (המוכיח והמאמת) יוצרים OTPs בתוך אותו חלון זמן (בדרך כלל באורך 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)
    

    לאחר שהמשתמש יוסיף את הסוד שלו לאפליקציית המאמת שלו, הוא יתחיל ליצור TOTPs.

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

מה הלאה