אם שדרגתם לאימות ב-Firebase באמצעות Identity Platform, אתם יכולים להוסיף אימות רב-שלבי באמצעות SMS לאפליקציית Flutter.
אימות רב-שלבי (MFA) משפר את האבטחה של האפליקציה. אמנם תוקפים לרוב חודרים לסיסמאות ולחשבונות ברשתות החברתיות, אבל קשה יותר ליירט הודעת טקסט.
לפני שמתחילים
מפעילים לפחות ספק אחד שתומך באימות רב-שלבי. כל הספקים תומכים באימות רב-שלבי, חוץ מאימות באמצעות הטלפון, אימות אנונימי ו-Apple Game Center.
מוודאים שהאפליקציה מאמתת את כתובות האימייל של המשתמשים. כדי להשתמש באימות רב-שלבי צריך לאמת את כתובת האימייל. כך אפשר למנוע מגורמים זדוניים להירשם לשירות באמצעות כתובת אימייל שלא שייכת להם, ואז לנעול את הבעלים האמיתי של הכתובת על ידי הוספת אמצעי אימות נוסף.
Android: אם עדיין לא הגדרתם את הגיבוב (hash) מסוג SHA-256 של האפליקציה ב-Firebase console, עליכם לעשות זאת. מידע על איתור הגיבוב (hash) מסוג SHA-256 של האפליקציה זמין במאמר בנושא אימות הלקוח.
iOS: ב-Xcode, מפעילים התראות Push לפרויקט ומוודאים שמפתח האימות של APNs מוגדר עם העברת הודעות בענן ב-Firebase (FCM). בנוסף, צריך להפעיל מצבי רקע להתראות מרחוק. לקבלת הסבר מפורט על השלב הזה, אפשר לעיין במסמכי התיעוד בנושא אימות טלפוני ב-Firebase ל-iOS.
אינטרנט: מוודאים שהוספתם את הדומיין של האפליקציה במסוף Firebase, בקטע דומיינים להפניה אוטומטית של OAuth.
הפעלת אימות רב-גורמי
פותחים את הדף Authentication > Sign-in method (אימות > שיטת כניסה) במסוף Firebase.
בקטע מתקדם, מפעילים את האפשרות אימות רב-גורמי באמצעות SMS.
כדאי גם להזין את מספרי הטלפון שבהם תשתמשו לבדיקת האפליקציה. אמנם לא חובה לרשום מספרי טלפון לבדיקה, אבל מומלץ מאוד לעשות זאת כדי להימנע מהגבלת קצב הבקשות במהלך הפיתוח.
אם עדיין לא אישרתם את הדומיין של האפליקציה, אתם צריכים להוסיף אותו לרשימת ההיתרים בדף אימות > הגדרות במסוף Firebase.
בחירת דפוס הרשמה
אתם יכולים לבחור אם האפליקציה שלכם דורשת אימות רב-שלבי, ואיך ומתי לרשום את המשתמשים. דוגמאות לדפוסים נפוצים:
רושמים את הגורם השני לאימות של המשתמש כחלק מההרשמה. כדאי להשתמש בשיטה הזו אם האפליקציה שלכם דורשת אימות רב-שלבי מכל המשתמשים.
הציעו אפשרות דילוג על הוספת אמצעי אימות נוסף במהלך ההרשמה. אפליקציות שרוצות לעודד אימות רב-גורמי, אבל לא מחייבות אותו, עשויות להעדיף את הגישה הזו.
אפשרות להוסיף אימות דו-שלבי מדף ניהול החשבון או הפרופיל של המשתמש, במקום ממסך ההרשמה. כך מצמצמים את החיכוך במהלך תהליך ההרשמה, ועדיין מאפשרים אימות רב-שלבי למשתמשים שחשובה להם האבטחה.
הוספה הדרגתית של שלב שני לאימות כשמשתמש רוצה לגשת לתכונות עם דרישות אבטחה מוגברות.
רישום של גורם שני
כדי לרשום גורם משני חדש למשתמש:
מאמתים מחדש את המשתמש.
מבקשים מהמשתמש להזין את מספר הטלפון שלו.
קבלת סשן עם אימות רב-שלבי עבור המשתמש:
final multiFactorSession = await user.multiFactor.getSession();מאמתים את מספר הטלפון באמצעות סשן עם אימות רב-שלבי והתקשרות חזרה:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: multiFactorSession, phoneNumber: phoneNumber, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // The SMS verification code has been sent to the provided phone number. // ... }, codeAutoRetrievalTimeout: (_) {}, );אחרי שקוד ה-SMS נשלח, מבקשים מהמשתמש לאמת את הקוד:
final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, );משלימים את ההרשמה:
await user.multiFactor.enroll( PhoneMultiFactorGenerator.getAssertion( credential, ), );
בדוגמה הבאה מוצג קוד מלא להוספת אימות דו-שלבי:
final session = await user.multiFactor.getSession();
final auth = FirebaseAuth.instance;
await auth.verifyPhoneNumber(
multiFactorSession: session,
phoneNumber: phoneController.text,
verificationCompleted: (_) {},
verificationFailed: (_) {},
codeSent: (String verificationId, int? resendToken) async {
// See `firebase_auth` example app for a method of retrieving user's sms code:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
final smsCode = await getSmsCodeFromUser(context);
if (smsCode != null) {
// Create a PhoneAuthCredential with the code
final credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
try {
await user.multiFactor.enroll(
PhoneMultiFactorGenerator.getAssertion(
credential,
),
);
} on FirebaseAuthException catch (e) {
print(e.message);
}
}
},
codeAutoRetrievalTimeout: (_) {},
);
כל הכבוד! הוספתם אמצעי אימות שני למשתמש.
כניסת משתמשים באמצעות גורם אימות שני
כדי להכניס משתמש באמצעות אימות דו-שלבי ב-SMS:
מבצעים כניסה של המשתמש באמצעות הגורם הראשון, ואז מאתרים את החריגה
FirebaseAuthMultiFactorException. השגיאה הזו מכילה רכיב לפתרון בעיות, שבעזרתו אפשר לקבל את הגורמים השניוניים שהמשתמש רשם. הוא גם מכיל סשן בסיסי שמוכיח שהמשתמש עבר אימות בהצלחה באמצעות הגורם הראשון.לדוגמה, אם הגורם הראשון של המשתמש היה אימייל וסיסמה:
try { await _auth.signInWithEmailAndPassword( email: emailController.text, password: passwordController.text, ); // User is not enrolled with a second factor and is successfully // signed in. // ... } on FirebaseAuthMultiFactorException catch (e) { // The user is a multi-factor user. Second factor challenge is required final resolver = e.resolver // ... }אם המשתמש רשום עם כמה אמצעי אימות משניים, צריך לשאול אותו באיזה מהם הוא רוצה להשתמש:
final session = e.resolver.session; final hint = e.resolver.hints[selectedHint];שליחת הודעת אימות לטלפון של המשתמש עם הרמז והסשן של אימות רב-שלבי:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: session, multiFactorInfo: hint, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // ... }, codeAutoRetrievalTimeout: (_) {}, );כדי להשלים את האימות המשני, צריך להתקשר אל
resolver.resolveSignIn():final smsCode = await getSmsCodeFromUser(context); if (smsCode != null) { // Create a PhoneAuthCredential with the code final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, ); try { await e.resolver.resolveSignIn( PhoneMultiFactorGenerator.getAssertion(credential) ); } on FirebaseAuthException catch (e) { print(e.message); } }
הקוד הבא מציג דוגמה מלאה לכניסה של משתמש עם אימות רב-שלבי:
try {
await _auth.signInWithEmailAndPassword(
email: emailController.text,
password: passwordController.text,
);
} on FirebaseAuthMultiFactorException catch (e) {
setState(() {
error = '${e.message}';
});
final firstHint = e.resolver.hints.first;
if (firstHint is! PhoneMultiFactorInfo) {
return;
}
await FirebaseAuth.instance.verifyPhoneNumber(
multiFactorSession: e.resolver.session,
multiFactorInfo: firstHint,
verificationCompleted: (_) {},
verificationFailed: (_) {},
codeSent: (String verificationId, int? resendToken) async {
// See `firebase_auth` example app for a method of retrieving user's sms code:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
final smsCode = await getSmsCodeFromUser(context);
if (smsCode != null) {
// Create a PhoneAuthCredential with the code
final credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
try {
await e.resolver.resolveSignIn(
PhoneMultiFactorGenerator.getAssertion(
credential,
),
);
} on FirebaseAuthException catch (e) {
print(e.message);
}
}
},
codeAutoRetrievalTimeout: (_) {},
);
} catch (e) {
...
}
כל הכבוד! התחברתם בהצלחה כמשתמש באמצעות אימות רב-שלבי.
המאמרים הבאים
- ניהול משתמשים עם אימות רב-שלבי באמצעות Admin SDK.