אם שדרגתם ל-Firebase Authentication with Identity Platform, תוכלו להוסיף לאפליקציה אימות רב-שלבי (MFA) באמצעות סיסמה חד-פעמית מבוססת-זמן (TOTP).
Firebase Authentication with Identity Platform מאפשר להשתמש ב-TOTP כגורם נוסף לאימות רב-שלבי. כשמפעילים את התכונה הזו, משתמשים שמנסים להיכנס לאפליקציה רואים בקשה ל-TOTP. כדי ליצור אותו, הם צריכים להשתמש באפליקציית אימות שיכולה ליצור קודי TOTP תקפים, כמו מאמת החשבונות של Google.
לפני שמתחילים
מפעילים ספק אחד לפחות שתומך ב-MFA. חשוב לזכור שכל הספקים למעט הספקים הבאים תומכים באימות דו-שלבי:
- אימות הטלפון
- אימות אנונימי
- טוקני אימות בהתאמה אישית
- Apple Game Center
חשוב לוודא שהאפליקציה מאמתת את כתובות האימייל של המשתמשים. כדי להשתמש בשיטת אימות דו-שלבי, צריך לאמת את כתובת האימייל. כך מונעים מגורמים זדוניים להירשם לשירות באמצעות כתובת אימייל שאינה בבעלות שלהם, ולאחר מכן לנעול את הבעלים האמיתי של כתובת האימייל על ידי הוספת גורם שני.
אם עדיין לא עשיתם זאת, צריך להתקין את Firebase Android SDK.
אפשר להשתמש בשיטת האימות הדו-שלבי באמצעות TOTP רק ב-Android SDK בגרסה 22.1.0 ואילך.
הפעלת אימות דו-שלבי באמצעות TOTP
כדי להפעיל את TOTP כגורם שני, משתמשים ב-Admin SDK או קוראים לנקודת הקצה של ה-REST של הגדרות הפרויקט.
כדי להשתמש ב-Admin SDK:
אם עדיין לא עשיתם זאת, מתקינים את ה-SDK של Firebase Admin עבור Node.js.
יש תמיכה בשיטת האימות הדו-שלבי באמצעות TOTP רק ב-SDK של Firebase Admin עבור Node.js בגרסה 11.6.0 ואילך.
מריצים את הפקודה הבאה:
import { getAuth } from 'firebase-admin/auth'; getAuth().projectConfigManager().updateProjectConfig( { multiFactorConfig: { providerConfigs: [{ state: "ENABLED", totpProviderConfig: { adjacentIntervals: NUM_ADJ_INTERVALS } }] } })
מחליפים את מה שכתוב בשדות הבאים:
NUM_ADJ_INTERVALS
: מספר הפסקות זמן סמוכות בחלון הזמן שמהן אפשר לקבל אסימוני TOTP, מ-0 עד 10. ערך ברירת המחדל הוא 5.המפתחות החד-פעמיים מבוססי TOTP פועלים כך: כששני צדדים (המוכיח והמאמת) יוצרים מפתחות חד-פעמיים באותו חלון זמן (בדרך כלל 30 שניות), הם יוצרים את אותה סיסמה. עם זאת, כדי להתאים את השעון בין הצדדים לזמן התגובה של האדם, אפשר להגדיר את שירות ה-TOTP כך שיקבל גם אסימוני TOTP מחלונות סמוכים.
כדי להפעיל אימות דו-שלבי באמצעות TOTP באמצעות ה-API ל-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
: מספר הפסקות בחלון הזמן, מ-0 עד 10. ערך ברירת המחדל הוא 5.המפתחות החד-פעמיים מבוססי TOTP פועלים כך: כששני צדדים (המוכיח והמאמת) יוצרים מפתחות חד-פעמיים באותו חלון זמן (בדרך כלל 30 שניות), הם יוצרים את אותה סיסמה. עם זאת, כדי להתאים את השעון בין הצדדים לזמן התגובה של האדם, אפשר להגדיר את שירות ה-TOTP כך שיקבל גם אסימוני TOTP מחלונות סמוכים.
בחירת דפוס ההרשמה
אתם יכולים לבחור אם האפליקציה תחייב אימות רב-שלבי, ואיך ומתי להירשם המשתמשים. דוגמאות לדפוסים נפוצים:
להירשם לגורם האימות השני של המשתמש כחלק מהרישום. כדאי להשתמש בשיטה הזו אם האפליקציה שלכם דורשת אימות רב-שלבי לכל המשתמשים.
כדאי להציע אפשרות לדלג על ההרשמה של גורם אימות שני במהלך ההרשמה. אם אתם רוצים לעודד את המשתמשים להשתמש באימות רב-שלבי באפליקציה, אבל לא לחייב אותם לעשות זאת, תוכלו להשתמש בגישה הזו.
אפשר להוסיף גורם אימות שני מהחשבון של המשתמש או מהדף לניהול הפרופיל, במקום במסך ההרשמה. כך אפשר לצמצם את החיכוך בתהליך ההרשמה, ועדיין להציע אימות רב-שלבי למשתמשים שמתעניינים באבטחה.
מחייב להוסיף גורם נוסף באופן מצטבר כשהמשתמש רוצה לגשת לתכונות עם דרישות אבטחה מחמירות יותר.
הרשמה של משתמשים לאימות דו-שלבי באמצעות TOTP
אחרי שמפעילים את אימות הגורם הנוסף מסוג TOTP כגורם שני באפליקציה, מטמיעים לוגיקה בצד הלקוח כדי לרשום משתמשים לאימות הגורם הנוסף מסוג TOTP:
מבצעים אימות מחדש של המשתמש.
יוצרים סוד 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.) } }
מציגים את הסוד למשתמש ומבקשים ממנו להזין אותו באפליקציית האימות:
// 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.
מבקשים מהמשתמש להקליד את קוד ה-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, משתמשים בקוד הבא:
קוראים לאחת מהשיטות עם
signInWith
כמו שאתם עושים אם אתם לא משתמשים בשיטת אימות דו-שלבי. (לדוגמה,signInWithEmailAndPassword()
). אם ה-method יוצרFirebaseAuthMultiFactorException
, מתחילים את תהליך האימות הדו-שלבי של האפליקציה.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.) // ... } } }
בתהליך האימות הדו-שלבי של האפליקציה, המשתמש צריך לבחור קודם את הגורם השני שבו הוא רוצה להשתמש. כדי לקבל רשימה של גורמים שניים נתמכים, בודקים את המאפיין
hints
של מכונהMultiFactorResolver
:val enrolledFactors = exception.resolver.hints.map { it.displayName }
אם המשתמש בוחר להשתמש ב-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.
אם משתמש נרשם לכמה אפשרויות של אימות דו-שלבי, והוא מבטל את ההרשמה מהאפשרות שהופעל לאחרונה, הוא יקבל הודעת 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.
}
}
}
}
המאמרים הבאים
- ניהול משתמשים עם אימות רב-גורמי באופן פרוגרמטי באמצעות Admin SDK.