אימות הטלפון

אימות באמצעות הטלפון מאפשר למשתמשים להיכנס ל-Firebase באמצעות הטלפון שלהם כמאמת. הודעת SMS נשלחת למשתמש (למספר הטלפון שצוין) עם קוד ייחודי. אחרי שהקוד מאושר, המשתמש יכול להיכנס ל-Firebase.

מספרי טלפון שמשתמשי קצה מספקים לצורך אימות יישלחו וייאוחסנו על ידי Google כדי לשפר את מניעת הספאם והניצול לרעה בשירות Google, כולל ב-Firebase, אבל לא רק. מפתחים צריכים לוודא שיש להם את ההסכמה המתאימה של משתמשי הקצה לפני שהם משתמשים בשירות הכניסה באמצעות מספר טלפון של Firebase Authentication.

אימות טלפון ב-Firebase לא נתמך בכל המדינות. למידע נוסף, אפשר לעיין בשאלות הנפוצות שלהם.

הגדרה

לפני שמתחילים להשתמש באימות טלפוני, חשוב לוודא שביצעתם את השלבים הבאים:

  1. במסוף Firebase, עוברים אל Security (אבטחה) >‏ Authentication (אימות).

  2. בכרטיסייה Sign in method (שיטת כניסה), מפעילים את ספק הכניסה Phone (טלפון).

  3. הגדרת דרישות ספציפיות לפלטפורמה:

    • iOS+‎: ב-Xcode,‏ מפעילים התראות פוש לפרויקט ומוודאים שמפתח האימות של APNs מוגדר עם העברת הודעות בענן ב-Firebase ‏ (FCM). בנוסף, צריך להפעיל מצבי רקע להתראות מרחוק.

      הסבר מפורט על השלב הזה מופיע במאמר אימות טלפוני ב-Firebase ל-iOS.

    • Android: אם עדיין לא עשיתם זאת, מציינים את טביעת האצבע מסוג SHA-1 של האפליקציה:

      1. במסוף Firebase, עוברים אל הגדרות > הכרטיסייה כללי.

      2. גוללים למטה אל הכרטיס האפליקציות שלך, בוחרים את אפליקציית Android ומוסיפים את טביעת האצבע מסוג SHA-1 בשדה טביעות אצבע של אישור SHA.

      במאמר אימות הלקוח מוסבר איך מקבלים את טביעת האצבע של ה-SHA של האפליקציה.

    • אינטרנט: אם עדיין לא עשיתם זאת, צריך לתת הרשאה לדומיין של האפליקציה:

      1. במסוף Firebase, עוברים אל Security (אבטחה) > Authentication (אימות) > הכרטיסייה Settings (הגדרות).

      2. בקטע דומיינים מורשים, לוחצים על הוספת דומיין ומוסיפים את הדומיין.

שימוש

ה-SDK של אימות ב-Firebase ל-Flutter מספק שתי דרכים נפרדות לאימות משתמש באמצעות מספר הטלפון שלו. פלטפורמות מקוריות (למשל Android ו-iOS) מספקות פונקציונליות שונה לאימות מספר טלפון מאשר האינטרנט, ולכן קיימות שתי שיטות לכל פלטפורמה באופן בלעדי:

  • פלטפורמה מקורית: verifyPhoneNumber.
  • פלטפורמת אינטרנט: signInWithPhoneNumber.

מודעה מותאמת: verifyPhoneNumber

בפלטפורמות מקוריות, קודם צריך לאמת את מספר הטלפון של המשתמש, ואז הוא יכול להיכנס לחשבון או לקשר אותו ל-PhoneAuthCredential.

קודם צריך לבקש מהמשתמש את מספר הטלפון שלו. אחרי שמספקים את הנתונים, מבצעים קריאה ל-method verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

יש 4 קריאות חוזרות (callback) נפרדות שצריך לטפל בהן, וכל אחת מהן תקבע איך לעדכן את ממשק המשתמש של האפליקציה:

  1. verificationCompleted: טיפול אוטומטי בקוד ה-SMS במכשירי Android.
  2. verificationFailed: טיפול באירועי כשל כמו מספרי טלפון לא תקינים או חריגה ממכסת ה-SMS.
  3. codeSent: טיפול במצב שבו קוד נשלח למכשיר מ-Firebase. משמש להצגת בקשה למשתמשים להזין את הקוד.
  4. codeAutoRetrievalTimeout: הגדרה של פסק זמן למקרה שטיפול אוטומטי בקוד SMS נכשל.

verificationCompleted

ה-handler הזה יופעל רק במכשירי Android שתומכים בפענוח אוטומטי של קודים ב-SMS.

כשקוד ה-SMS מועבר למכשיר, מערכת Android מאמתת אותו באופן אוטומטי בלי שהמשתמש צריך להזין אותו ידנית. אם האירוע הזה מתרחש, המערכת מספקת באופן אוטומטי PhoneAuthCredential שאפשר להשתמש בו כדי להיכנס לחשבון עם מספר הטלפון של המשתמש או לקשר את מספר הטלפון לחשבון.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

verificationFailed

אם Firebase מחזיר שגיאה, למשל אם מספר הטלפון שגוי או אם חרגתם ממכסת ה-SMS של הפרויקט, יועבר FirebaseAuthException ל-handler הזה. במקרה כזה, תציגו למשתמש הודעה על כך שמשהו השתבש, בהתאם לקוד השגיאה.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

codeSent

כש-Firebase שולח קוד SMS למכשיר, ה-handler הזה מופעל עם verificationId ו-resendToken (resendToken נתמך רק במכשירי Android, במכשירי iOS תמיד יוחזר ערך null).

אחרי שהאירוע מופעל, זה הזמן לעדכן את ממשק המשתמש של האפליקציה כדי לבקש מהמשתמש להזין את קוד ה-SMS שהוא מצפה לקבל. אחרי שמזינים את הקוד שמתקבל ב-SMS, אפשר לשלב את מזהה האימות עם הקוד שמתקבל ב-SMS כדי ליצור PhoneAuthCredentialחדש:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

כברירת מחדל, Firebase לא ישלח מחדש הודעת SMS חדשה אם היא נשלחה לאחרונה. אבל אפשר לשנות את ההתנהגות הזו על ידי קריאה חוזרת של המתודה verifyPhoneNumber עם אסימון השליחה מחדש לארגומנט forceResendingToken. אם הפעולה תצליח, הודעת ה-SMS תישלח מחדש.

codeAutoRetrievalTimeout

במכשירי Android שתומכים בפענוח אוטומטי של קוד SMS, ה-handler הזה יופעל אם המכשיר לא פענח אוטומטית הודעת SMS בתוך פרק זמן מסוים. אחרי שהתקופה הזו תסתיים, המכשיר לא ינסה יותר לפתור בעיות שקשורות להודעות נכנסות.

כברירת מחדל, המכשיר ממתין 30 שניות, אבל אפשר לשנות את זה באמצעות הארגומנט timeout:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

באינטרנט: signInWithPhoneNumber

בפלטפורמות אינטרנט, משתמשים יכולים להיכנס לחשבון על ידי אישור שיש להם גישה לטלפון, באמצעות הזנת קוד ה-SMS שנשלח למספר הטלפון שצוין. כדי להוסיף אבטחה ולמנוע ספאם, המשתמשים מתבקשים להוכיח שהם בני אדם על ידי השלמת ווידג'ט של Google reCAPTCHA. אחרי האישור, יישלח קוד ה-SMS.

ערכת ה-SDK של אימות ב-Firebase ל-Flutter תנהל את ווידג'ט ה-reCAPTCHA כברירת מחדל, אבל היא מאפשרת שליטה באופן שבו הוא מוצג ומוגדר אם נדרש. כדי להתחיל, מבצעים קריאה ל-signInWithPhoneNumber עם מספר הטלפון.

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

הפעלת השיטה תגרום קודם להצגת הווידג'ט של reCAPTCHA. המשתמש צריך להשלים את הבדיקה לפני שנשלח אליו קוד באימות באמצעות SMS. אחרי שהתהליך מסתיים, אפשר להזין את קוד ה-SMS לשיטה confirm בתגובה ConfirmationResult שהתקבלה כדי שהמשתמש יוכל להיכנס:

UserCredential userCredential = await confirmationResult.confirm('123456');

בדומה לתהליכי כניסה אחרים, כניסה מוצלחת תפעיל את כל מאזיני מצב האימות שנרשמתם אליהם באפליקציה.

הגדרת reCAPTCHA

ווידג'ט reCAPTCHA הוא תהליך מנוהל מלא שמספק אבטחה לאפליקציית האינטרנט שלכם.

הארגומנט השני של signInWithPhoneNumber מקבל מופע אופציונלי של RecaptchaVerifier שאפשר להשתמש בו כדי לנהל את הווידג'ט. כברירת מחדל, הווידג'ט יוצג כווידג'ט בלתי נראה כשתופעל זרימת הכניסה. ווידג'ט 'בלתי נראה' יופיע כחלון מודאלי במסך מלא מעל האפליקציה.

עם זאת, אפשר להציג ווידג'ט מוטבע שהמשתמש צריך ללחוץ עליו באופן מפורש כדי לאמת את עצמו.

כדי להוסיף ווידג'ט מוטבע, מציינים מזהה של רכיב DOM בארגומנט container של מופע RecaptchaVerifier. הרכיב חייב להתקיים ולהיות ריק, אחרת תוצג שגיאה. אם לא מספקים ארגומנט container, הווידג'ט יוצג כ'בלתי נראה'.

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

אפשר לשנות את הגודל והעיצוב באמצעות התאמה אישית של הארגומנטים size ו-theme כמו שמוצג למעלה.

אפשר גם להגדיר האזנה לאירועים, כמו השלמת ה-reCAPTCHA על ידי המשתמש, פקיעת התוקף של ה-reCAPTCHA או השלכת שגיאה:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

בדיקה

ב-Firebase יש תמיכה בבדיקה מקומית של מספרי טלפון:

  1. במסוף Firebase, בוחרים את ספק האימות 'טלפון' ולוחצים על התפריט הנפתח 'מספרי טלפון לבדיקה'.
  2. מזינים מספר טלפון חדש (למשל, +44 7444 555666) וקוד בדיקה (למשל, 123456).

אם תספקו מספר טלפון לבדיקה באחת מהשיטות verifyPhoneNumber או signInWithPhoneNumber, לא יישלח SMS בפועל. במקום זאת, אפשר לספק את קוד הבדיקה ישירות ל-PhoneAuthProvider או באמצעות signInWithPhoneNumbers handler לאישור תוצאות.