אימות עם Firebase באמצעות קישור לאימייל ב-Android

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

יש הרבה יתרונות לכניסה באמצעות אימייל:

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

לפני שמתחילים

הגדרת פרויקט Android

  1. אם עדיין לא עשיתם זאת, עליכם להוסיף את Firebase לפרויקט Android שלכם.

  2. בקובץ Gradle של המודול (ברמת האפליקציה) (בדרך כלל <project>/<app-module>/build.gradle.kts או <project>/<app-module>/build.gradle), מוסיפים את התלות בספריית Firebase Authentication ל-Android. מומלץ להשתמש ב-Firebase Android BoM כדי לשלוט בניהול הגרסאות של הספריות.

    בנוסף, במסגרת ההגדרה של Firebase Authentication, צריך להוסיף את Google Play services SDK לאפליקציה.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:35.0.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:22.0.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:25.0.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:22.0.0")
    }

הפעלת כניסה באמצעות קישור באימייל בפרויקט Firebase

כדי לאפשר למשתמשים להיכנס באמצעות קישור באימייל, קודם צריך להפעיל את ספק האימייל ואת שיטת הכניסה באמצעות קישור באימייל בפרויקט Firebase:

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

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

  3. באותו קטע, מפעילים את ספק הכניסה Email link (passwordless sign-in) (קישור באימייל – כניסה ללא סיסמה).

  4. לוחצים על שמירה.

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

  1. יוצרים את האובייקט ActionCodeSettings, שמספק ל-Firebase הוראות לגבי אופן יצירת הקישור באימייל. מגדירים את השדות הבאים:

    • ‫url: קישור העומק להטמעה וכל מצב נוסף שרוצים להעביר. אם עדיין לא עשיתם את זה, מוסיפים את הדומיין של הקישור לרשימת הדומיינים המורשים:

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

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

      אם האפליקציה לא מותקנת במכשיר של המשתמש ולא ניתן להתקין אותה, הקישור יפנה את המשתמש לכתובת ה-URL הזו.

    • ‫androidPackageName ו-iOSBundleId: עוזרים ל-Firebase Authentication לקבוע אם ליצור קישור לאינטרנט בלבד או קישור לנייד שנפתח במכשיר Android או Apple.
    • ‫handleCodeInApp: מוגדר ל-true. פעולת הכניסה תמיד צריכה להתבצע באפליקציה, בניגוד לפעולות אחרות באימייל מחוץ לפס (איפוס סיסמה ואימותים באימייל). הסיבה לכך היא שבסוף התהליך, המשתמש אמור להיות מחובר לחשבון ומצב האימות שלו אמור להישמר באפליקציה.
    • ‫linkDomain: כשמוגדרים דומיינים מותאמים אישית Hosting של קישורים לפרויקט, צריך לציין באיזה מהם להשתמש כשפותחים את הקישור באפליקציה ספציפית לנייד. אחרת, הדומיין שמוגדר כברירת מחדל נבחר באופן אוטומטי (לדוגמה, PROJECT_ID.firebaseapp.com).
    • ‫dynamicLinkDomain: הוצא משימוש. לא מציינים את הפרמטר הזה.

    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 זמין בקטע העברת מצב בפעולות באימייל.

  2. בקשת כתובת האימייל מהמשתמש.

  3. שולחים את קישור האימות לכתובת האימייל של המשתמש ושומרים את כתובת האימייל של המשתמש למקרה שהמשתמש ישלים את הכניסה באמצעות האימייל באותו מכשיר.

    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 Authentication דורש לספק את כתובת האימייל של המשתמש כשמשלימים את תהליך הכניסה. כדי שהכניסה תתבצע בהצלחה, כתובת האימייל הזו צריכה להיות זהה לכתובת שאליה נשלח במקור קישור הכניסה.

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

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

בנוסף, חשוב להשתמש בכתובת URL מסוג HTTPS בסביבת הייצור כדי למנוע מצב שבו שרתים מתווכים עלולים ליירט את הקישור.

השלמת הכניסה לחשבון באפליקציית Android

‫Firebase Authentication משתמש ב-Firebase Hosting כדי לשלוח את הקישור באימייל למכשיר נייד. כדי להשלים את הכניסה דרך אפליקציה לנייד, צריך להגדיר את האפליקציה כך שתזהה את קישור האפליקציה הנכנס, תנתח את קישור העומק הבסיסי ואז תשלים את הכניסה. מידע נוסף זמין במאמרי העזרה בנושא קישורי אפליקציות ל-Android.

הגדרה של Firebase Hosting

‫Firebase Authentication משתמש בדומיינים של Firebase Hosting כשיוצרים ושולחים קישור שנועד להיפתח באפליקציה לנייד. כבר הגדרנו בשבילכם דומיין Firebase Hosting כברירת מחדל.

  1. הגדרת דומיינים של Firebase Hosting:

    במסוף Firebase, נכנסים אל Hosting & Serverless >‏ Hosting.

    • אם רוצים להשתמש בדומיין שמוגדר כברירת מחדל לקישור לאימייל שנפתח באפליקציות לנייד, צריך לעבור לאתר שמוגדר כברירת מחדל ולרשום את דומיין Hosting ברירת המחדל. דומיין ברירת מחדל Hosting בדרך כלל נראה כך: PROJECT_ID.firebaseapp.com.

      תצטרכו את הערך הזה כשמגדירים את האפליקציה ליירוט הקישור הנכנס.

    • אם אתם רוצים להשתמש בדומיין מותאם אישית לקישור לאימייל, אתם יכולים להירשם לדומיין ב-Firebase Hosting ולהשתמש בו לדומיין של הקישור.

  2. הגדרת אפליקציות ל-Android:

    כדי לטפל בקישורים האלה מאפליקציה ל-Android, צריך לציין את שם החבילה של האפליקציה בהגדרות הפרויקט ב-Firebase Console. בנוסף, צריך לספק את SHA-1 ו-SHA-256 של אישור האפליקציה.

    אם רוצים שהקישורים האלה יפנו לפעילות ספציפית, צריך להגדיר מסנן Intent בקובץ AndroidManifest.xml. מסנן הכוונה צריך לזהות קישורים לאימייל בדומיין שלכם. ב-AndroidManifest.xml:

    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <category android:name="android.intent.category.DEFAULT" />
      <data
        android:scheme="https"
        android:host="<PROJECT_ID>.firebaseapp.com or your custom domain"
        android:pathPrefix="/__/auth/links" />
    </intent-filter>
    

    כשמשתמשים פותחים קישור לאירוח עם הנתיב /__/auth/links, הסכימה והמארח שציינתם, האפליקציה תתחיל את הפעילות עם מסנן הכוונות הזה כדי לטפל בקישור.

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

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());
                    }
                }
            });
}

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

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

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

ההבדל יהיה במחצית השנייה של הפעולה:

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());
                }
            }
        });

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

בעבר, אימות באמצעות קישור באימייל הסתמך על Firebase Dynamic Links, שייצא משימוש ב-25 באוגוסט 2025.

פרסמנו פתרון חלופי ב-Firebase Authentication Android SDK v23.2.0+‎ וב-Firebase BoM v33.9.0+‎.

אם האפליקציה שלכם משתמשת בקישורים מהסוג הישן, כדאי להעביר את האפליקציה למערכת החדשה שמבוססת על Firebase Hosting.

אם יצרתם את הפרויקט ב-15 בספטמבר 2023 או אחרי, ההגנה מפני ספירת כתובות אימייל מופעלת כברירת מחדל. התכונה הזו משפרת את האבטחה של חשבונות המשתמשים בפרויקט, אבל היא משביתה את השיטה fetchSignInMethodsForEmail(), שבעבר המלצנו להשתמש בה כדי להטמיע תהליכים שמתחילים בזיהוי.

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

פרטים נוספים זמינים במאמר בנושא הגנה מפני ספירת כתובות אימייל.

השלבים הבאים

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

  • באפליקציות, אפשר לקבל את פרטי הפרופיל הבסיסיים של המשתמש מאובייקט FirebaseUser. מידע נוסף זמין במאמר בנושא ניהול משתמשים.

  • בFirebase Realtime Database ובCloud Storage כללי האבטחה, אפשר לקבל את מזהה המשתמש הייחודי של המשתמש המחובר מהמשתנה auth, ולהשתמש בו כדי לקבוע לאילו נתונים המשתמש יכול לגשת.

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

כדי להוציא משתמש מהחשבון, מתקשרים אל signOut:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();