אתם יכולים להשתמש באימות ב-Firebase כדי לשלוח לאימייל של המשתמש קישור, שבו הוא יוכל ללחוץ כדי להיכנס לחשבון. בתהליך הזה מתבצעת גם אימות של כתובת האימייל של המשתמש.
יש יתרונות רבים לכניסה באמצעות אימייל:
- הרשמה וכניסה ללא טרחה.
- סיכון נמוך יותר לשימוש חוזר בסיסמה באפליקציות שונות, שעלול לפגוע באבטחה גם של סיסמאות שנבחרו היטב.
- היכולת לאמת משתמש תוך אימות שהוא הבעלים החוקיים של כתובת האימייל.
- כדי להיכנס, המשתמש צריך רק חשבון אימייל נגיש. אין צורך להיות הבעלים של מספר טלפון או חשבון ברשת חברתית.
- המשתמש יכול להיכנס לחשבון באופן מאובטח בלי לספק (או לזכור) סיסמה, שיכולה להיות מסורבלת במכשיר נייד.
- משתמש קיים שנכנס בעבר באמצעות מזהה אימייל (סיסמה או איחוד) יכול לשדרג את החשבון שלו כך שיוכל להיכנס באמצעות כתובת האימייל בלבד. לדוגמה, משתמש ששכח את הסיסמה עדיין יכול להיכנס לחשבון בלי לאפס את הסיסמה.
לפני שמתחילים
הגדרת הפרויקט ל-Android
אם עדיין לא עשיתם זאת, מוסיפים את Firebase לפרויקט Android.
בקובץ Gradle של המודול (ברמת האפליקציה) (בדרך כלל
<project>/<app-module>/build.gradle.kts
או<project>/<app-module>/build.gradle
), מוסיפים את התלות בספרייה Firebase Authentication ל-Android. מומלץ להשתמש ב-Firebase Android BoM כדי לשלוט בגרסאות הספרייה.בנוסף, כחלק מהגדרת Firebase Authentication, צריך להוסיף לאפליקציה את ה-SDK של Google Play Services.
dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:33.7.0")) // Add the dependency for the Firebase Authentication library // When using the BoM, you don't specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-auth")
// Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0") }כשמשתמשים ב-Firebase Android BoM, האפליקציה תמיד תשתמש בגרסאות תואמות של ספריות Firebase ל-Android.
(חלופה) מוסיפים יחסי תלות לספריות של Firebase בלי להשתמש ב-BoM
אם בוחרים לא להשתמש ב-Firebase BoM, צריך לציין את כל הגרסאות של ספריות Firebase בשורת התלות שלהן.
שימו לב: אם אתם משתמשים במספר ספריות של Firebase באפליקציה, מומלץ מאוד להשתמש ב-BoM כדי לנהל את הגרסאות של הספריות, וכך לוודא שכל הגרסאות תואמות.
dependencies { // Add the dependency for the Firebase Authentication library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-auth:23.1.0")
// Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0") }
הפעלת הכניסה באמצעות קישור לאימייל בפרויקט Firebase
כדי לאפשר למשתמשים להיכנס באמצעות קישור באימייל, קודם צריך להפעיל את ספק האימייל ואת שיטת הכניסה באמצעות קישור באימייל בפרויקט Firebase:
- במסוף Firebase, פותחים את הקטע Auth.
- בכרטיסייה Sign in method (שיטת כניסה), מפעילים את הספק Email/Password (אימייל/סיסמה). חשוב לזכור: כדי להשתמש בכניסה באמצעות קישור לאימייל, צריך להפעיל את הכניסה באמצעות כתובת אימייל/סיסמה.
- באותו קטע, מפעילים את שיטת הכניסה קישור לאימייל (כניסה ללא סיסמה).
- לוחצים על שמירה.
שליחת קישור אימות לכתובת האימייל של המשתמש
כדי להתחיל את תהליך האימות, מציגים למשתמש ממשק שמבקש ממנו לספק את כתובת האימייל שלו, ולאחר מכן קוראים ל-sendSignInLinkToEmail
כדי לבקש מ-Firebase לשלוח את הקישור לאימות לכתובת האימייל של המשתמש.
יוצרים את האובייקט ActionCodeSettings, שמספק ל-Firebase הוראות ליצירת הקישור באימייל. מגדירים את השדות הבאים:
url
: קישור העומק להטמעה וכל מצב נוסף שרוצים להעביר. הדומיין של הקישור צריך להיכלל ברשימת ההיתרים של הדומיינים המורשים במסוף Firebase. כדי למצוא את הרשימה הזו, עוברים לכרטיסייה 'שיטת כניסה' (Authentication -> Sign-in method). הקישור יפנה את המשתמש לכתובת ה-URL הזו אם האפליקציה לא מותקנת במכשיר שלו ולא ניתן היה להתקין אותה.androidPackageName
ו-IOSBundleId
: האפליקציות שבהן משתמשים כשפותחים את הקישור לכניסה במכשיר Android או Apple. איך מגדירים קישורים דינמיים של Firebase כדי לפתוח קישורי פעולה באימייל דרך אפליקציות לניידhandleCodeInApp
: מוגדר כ-true. תמיד צריך להשלים את פעולת הכניסה באפליקציה, בניגוד לפעולות אחרות באימייל מחוץ לצ'אט (איפוס סיסמה ואימותים באימייל). הסיבה לכך היא שבסוף התהליך, המשתמש אמור להיות מחובר לחשבון ומצב האימות שלו נשמר באפליקציה.dynamicLinkDomain
: כשמגדירים כמה דומיינים של קישורים דינמיים מותאמים אישית לפרויקט, צריך לציין באיזה מהם להשתמש כשהקישור נפתח דרך אפליקציה ספציפית לנייד (לדוגמה,example.page.link
). אחרת, הדומיין הראשון ייבחר באופן אוטומטי.
Kotlin
val actionCodeSettings = actionCodeSettings { // URL you want to redirect back to. The domain (www.example.com) for this // URL must be whitelisted in the Firebase Console. url = "https://www.example.com/finishSignUp?cartId=1234" // This must be true handleCodeInApp = true setIOSBundleId("com.example.ios") setAndroidPackageName( "com.example.android", true, // installIfNotAvailable "12", // minimumVersion ) }
Java
ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder() // URL you want to redirect back to. The domain (www.example.com) for this // URL must be whitelisted in the Firebase Console. .setUrl("https://www.example.com/finishSignUp?cartId=1234") // This must be true .setHandleCodeInApp(true) .setIOSBundleId("com.example.ios") .setAndroidPackageName( "com.example.android", true, /* installIfNotAvailable */ "12" /* minimumVersion */) .build();
מידע נוסף על ActionCodeSettings זמין בקטע העברת מצב בפעולות אימייל.
מבקשים מהמשתמש את כתובת האימייל שלו.
שולחים את הקישור לאימות לכתובת האימייל של המשתמש, ושומרים את כתובת האימייל של המשתמש למקרה שהמשתמש ישלים את תהליך הכניסה באמצעות האימייל באותו מכשיר.
Kotlin
Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings) .addOnCompleteListener { task -> if (task.isSuccessful) { Log.d(TAG, "Email sent.") } }
Java
FirebaseAuth auth = FirebaseAuth.getInstance(); auth.sendSignInLinkToEmail(email, actionCodeSettings) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Log.d(TAG, "Email sent."); } } });
השלמת הכניסה באמצעות הקישור באימייל
חששות אבטחה
כדי למנוע שימוש בקישור כניסה כדי להיכנס לחשבון בתור משתמש לא רצוי או במכשיר לא רצוי, אימות Firebase מחייב לספק את כתובת האימייל של המשתמש במהלך תהליך הכניסה. כדי שהכניסה תתבצע, כתובת האימייל הזו צריכה להתאים לכתובת שאליה נשלח הקישור לכניסה במקור.
כדי לייעל את התהליך הזה למשתמשים שפותחים את הקישור לכניסה באותו מכשיר שבו הם מבקשים את הקישור, אפשר לשמור את כתובת האימייל שלהם באופן מקומי – למשל באמצעות SharedPreferences – כששולחים את האימייל לכניסה. לאחר מכן, תוכלו להשתמש בכתובת הזו כדי להשלים את התהליך. אין להעביר את כתובת האימייל של המשתמש בפרמטרים של כתובת ה-URL להפניה אוטומטית ולהשתמש בה שוב, כי הפעולות האלה עלולות לאפשר הזרקות של סשנים.
בסיום הכניסה, כל מנגנון כניסה קודם לא מאומת יוסר מהמשתמש וכל הסשנים הקיימים יבוטלו. לדוגמה, אם מישהו יצר בעבר חשבון לא מאומת עם אותה כתובת אימייל וסיסמה, הסיסמה של המשתמש תוסר כדי למנוע מהמתחזה שטען לבעלות על החשבון הזה ויצר אותו להיכנס שוב באמצעות כתובת האימייל והסיסמה הלא מאומתות.
בנוסף, חשוב להשתמש בכתובת URL מסוג HTTPS בסביבת הייצור כדי למנוע משרתי ביניים ליירט את הקישור.
השלמת הכניסה באפליקציה ל-Android
האימות ב-Firebase משתמש בקישורים דינמיים ב-Firebase כדי לשלוח את הקישור לאימייל למכשיר נייד. כדי להשלים את הכניסה דרך אפליקציה לנייד, צריך להגדיר את האפליקציה כך שתזהה את הקישור לאפליקציה הנכנס, תנתח את קישור העומק הבסיסי ואז תשלים את הכניסה.
הגדרת קישורים דינמיים ב-Firebase
כששולחים קישור שנועד להיפתח באפליקציה לנייד, Firebase Auth משתמש בקישורים דינמיים ב-Firebase. כדי להשתמש בתכונה הזו, צריך להגדיר קישורים דינמיים במסוף Firebase.
מפעילים את הקישורים הדינמיים ב-Firebase:
- במסוף Firebase, פותחים את הקטע Dynamic Links.
-
אם עדיין לא אישרתם את התנאים של Dynamic Links ויצרתם דומיין Dynamic Links, עליכם לעשות זאת עכשיו.
אם כבר יצרתם דומיין Dynamic Links, שימו לב אליו. דומיין Dynamic Links בדרך כלל נראה כמו הדוגמה הבאה:
example.page.link
תצטרכו את הערך הזה כשתקבעו שהאפליקציה שלכם ל-Apple או ל-Android תוכל ליירט את הקישור הנכנס.
הגדרת אפליקציות ל-Android:
- כדי לטפל בקישורים האלה מאפליקציית Android, צריך לציין את שם החבילה של Android בהגדרות הפרויקט במסוף Firebase. בנוסף, צריך לספק את SHA-1 ו-SHA-256 של אישור האפליקציה.
- עכשיו, אחרי שהוספתם דומיין של קישור דינמי וווידאתם שאפליקציית Android מוגדרת בצורה נכונה, הקישור הדינמי יפנה לאפליקציה שלכם, החל מפעילות מרכז האפליקציות.
- אם רוצים שהקישור הדינמי יפנה אוטומטית לפעילות ספציפית, צריך להגדיר מסנן כוונה בקובץ AndroidManifest.xml. כדי לעשות זאת, מציינים את הדומיין של הקישור הדינמי או את הטיפול בפעולות אימייל במסנן ה-Intent. כברירת מחדל, ה-handler של פעולת האימייל מתארח בדומיין כמו בדוגמה הבאה:
PROJECT_ID.firebaseapp.com/
- הערות:
- אל תציינו את כתובת ה-URL שהגדרתם ב-actionCodeSettings במסנן הכוונה.
- כשיוצרים את הדומיין של הקישורים הדינמיים, יכול להיות שיצרתם גם קישור לכתובת URL מקוצרת. כתובת ה-URL הקצרה הזו לא תועבר. אל תגדירו את מסנן ה-Intent כך שיזהה אותה באמצעות המאפיין
android:pathPrefix
. המשמעות היא שלא תוכלו לזהות קישורים דינמיים שונים בחלקים שונים של האפליקציה. עם זאת, אפשר לבדוק את פרמטר השאילתהmode
בקישור כדי לראות איזו פעולה מנסים לבצע, או להשתמש בשיטות SDK כמוisSignInWithEmailLink
כדי לבדוק אם קישור שהאפליקציה קיבלה עושה את מה שאתם רוצים.
- למידע נוסף על קבלת קישורים דינמיים, אפשר לעיין במאמר הוראות לקבלת קישורים דינמיים ל-Android.
אימות הקישור והרשמה
אחרי שתקבלו את הקישור כפי שמתואר למעלה, עליכם לוודא שהוא מיועד לאימות באמצעות קישור באימייל ולהשלים את הכניסה.
Kotlin
val auth = Firebase.auth val intent = intent val emailLink = intent.data.toString() // Confirm the link is a sign-in with email link. if (auth.isSignInWithEmailLink(emailLink)) { // Retrieve this from wherever you stored it val email = "someemail@domain.com" // The client SDK will parse the code from the link for you. auth.signInWithEmailLink(email, emailLink) .addOnCompleteListener { task -> if (task.isSuccessful) { Log.d(TAG, "Successfully signed in with email link!") val result = task.result // You can access the new user via result.getUser() // Additional user info profile *not* available via: // result.getAdditionalUserInfo().getProfile() == null // You can check if the user is new or existing: // result.getAdditionalUserInfo().isNewUser() } else { Log.e(TAG, "Error signing in with email link", task.exception) } } }
Java
FirebaseAuth auth = FirebaseAuth.getInstance(); Intent intent = getIntent(); String emailLink = intent.getData().toString(); // Confirm the link is a sign-in with email link. if (auth.isSignInWithEmailLink(emailLink)) { // Retrieve this from wherever you stored it String email = "someemail@domain.com"; // The client SDK will parse the code from the link for you. auth.signInWithEmailLink(email, emailLink) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { Log.d(TAG, "Successfully signed in with email link!"); AuthResult result = task.getResult(); // You can access the new user via result.getUser() // Additional user info profile *not* available via: // result.getAdditionalUserInfo().getProfile() == null // You can check if the user is new or existing: // result.getAdditionalUserInfo().isNewUser() } else { Log.e(TAG, "Error signing in with email link", task.getException()); } } }); }
למידע נוסף על אופן הטיפול בכניסה באמצעות קישור לאימייל באפליקציה של Apple, אפשר לעיין במדריך לפלטפורמות של Apple.
במדריך לאפליקציות אינטרנט מוסבר איך מטפלים בכניסה באמצעות קישור לאימייל באפליקציית אינטרנט.
קישור או אימות מחדש באמצעות קישור באימייל
אפשר גם לקשר את שיטת האימות הזו למשתמש קיים. לדוגמה, משתמש שעבר אימות באמצעות ספק אחר, כמו מספר טלפון, יכול להוסיף את שיטת הכניסה הזו לחשבון הקיים שלו.
ההבדל יהיה במחצית השנייה של הפעולה:
Kotlin
// Construct the email link credential from the current URL. val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink) // Link the credential to the current user. Firebase.auth.currentUser!!.linkWithCredential(credential) .addOnCompleteListener { task -> if (task.isSuccessful) { Log.d(TAG, "Successfully linked emailLink credential!") val result = task.result // You can access the new user via result.getUser() // Additional user info profile *not* available via: // result.getAdditionalUserInfo().getProfile() == null // You can check if the user is new or existing: // result.getAdditionalUserInfo().isNewUser() } else { Log.e(TAG, "Error linking emailLink credential", task.exception) } }
Java
// Construct the email link credential from the current URL. AuthCredential credential = EmailAuthProvider.getCredentialWithLink(email, emailLink); // Link the credential to the current user. auth.getCurrentUser().linkWithCredential(credential) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { Log.d(TAG, "Successfully linked emailLink credential!"); AuthResult result = task.getResult(); // You can access the new user via result.getUser() // Additional user info profile *not* available via: // result.getAdditionalUserInfo().getProfile() == null // You can check if the user is new or existing: // result.getAdditionalUserInfo().isNewUser() } else { Log.e(TAG, "Error linking emailLink credential", task.getException()); } } });
אפשר להשתמש בכך גם כדי לבצע אימות מחדש של משתמש עם קישור לאימייל לפני שמריצים פעולה עם מידע רגיש.
Kotlin
// Construct the email link credential from the current URL. val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink) // Re-authenticate the user with this credential. Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential) .addOnCompleteListener { task -> if (task.isSuccessful) { // User is now successfully reauthenticated } else { Log.e(TAG, "Error reauthenticating", task.exception) } }
Java
// Construct the email link credential from the current URL. AuthCredential credential = EmailAuthProvider.getCredentialWithLink(email, emailLink); // Re-authenticate the user with this credential. auth.getCurrentUser().reauthenticateAndRetrieveData(credential) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { // User is now successfully reauthenticated } else { Log.e(TAG, "Error reauthenticating", task.getException()); } } });
עם זאת, מכיוון שהתהליך עשוי להסתיים במכשיר אחר שבו המשתמש המקורי לא היה מחובר לחשבון, יכול להיות שהתהליך לא יושלם. במקרה כזה, אפשר להציג למשתמש הודעת שגיאה כדי לאלץ אותו לפתוח את הקישור באותו מכשיר. אפשר להעביר מצב מסוים בקישור כדי לספק מידע על סוג הפעולה ועל מזהה המשתמש.
הוצא משימוש: הבחנה בין כתובת אימייל עם סיסמה לבין קישור לאימייל
אם יצרתם את הפרויקט ב-15 בספטמבר 2023 או לאחר מכן, ההגנה מפני ספירת כתובות אימייל מופעלת כברירת מחדל. התכונה הזו משפרת את האבטחה של חשבונות המשתמשים בפרויקט, אבל היא משביתה את השיטה fetchSignInMethodsForEmail()
, שבעבר המלצנו להשתמש בה כדי להטמיע תהליכים שמתחילים במזהה.
אפשר להשבית את ההגנה על ספירת כתובות האימייל בפרויקט, אבל אנחנו ממליצים לא לעשות זאת.
למידע נוסף, עיינו במסמכי העזרה בנושא הגנה מפני ספירת כתובות אימייל.
השלבים הבאים
אחרי שמשתמש נכנס לחשבון בפעם הראשונה, נוצר חשבון משתמש חדש שמקושר לפרטי הכניסה – כלומר שם המשתמש והסיסמה, מספר הטלפון או פרטי ספק האימות – שבאמצעותם המשתמש נכנס לחשבון. החשבון החדש הזה מאוחסן כחלק מפרויקט Firebase, וניתן להשתמש בו כדי לזהות משתמש בכל האפליקציות בפרויקט, ללא קשר לאופן שבו המשתמש נכנס לחשבון.
-
באפליקציות, אפשר לקבל את פרטי הפרופיל הבסיסיים של המשתמש מהאובייקט
FirebaseUser
. ניהול משתמשים בכללי האבטחה של Firebase Realtime Database ו-Cloud Storage, אפשר לקבל את מזהה המשתמש הייחודי של המשתמש שנכנס לחשבון מהמשתנה
auth
, ולהשתמש בו כדי לקבוע לאילו נתונים למשתמש תהיה גישה.
כדי לאפשר למשתמשים להיכנס לאפליקציה באמצעות כמה ספקי אימות, אפשר לקשר את פרטי הכניסה של ספק האימות לחשבון משתמש קיים.
כדי להוציא משתמש מהחשבון, קוראים לפונקציה
signOut
:
Kotlin
Firebase.auth.signOut()
Java
FirebaseAuth.getInstance().signOut();