בצע אימות עם Firebase באמצעות קישור דוא"ל באנדרואיד

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

ישנן יתרונות רבים לכניסה בדוא"ל:

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

לפני שאתה מתחיל

הגדר את פרויקט האנדרואיד שלך

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

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

    כמו כן, כחלק מהגדרת אימות Firebase, עליך להוסיף את ה-SDK של שירותי Google Play לאפליקציה שלך.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:32.8.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.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:22.3.1")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.0.0")
    }
    מחפש מודול ספרייה ספציפי לקוטלין? החל מאוקטובר 2023 (Firebase BoM 32.5.0) , מפתחי Kotlin ו-Java יכולים להיות תלויים במודול הספרייה הראשי (לפרטים, עיין בשאלות הנפוצות לגבי יוזמה זו ).

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

  1. במסוף Firebase , פתח את הקטע Auth .
  2. בכרטיסייה שיטת כניסה , הפעל את ספק הדוא"ל/סיסמה . שים לב שכניסה לדוא"ל/סיסמה חייבת להיות מופעלת כדי להשתמש בכניסה לקישור דוא"ל.
  3. באותו קטע, הפעל את שיטת הכניסה של קישור דוא"ל (כניסה ללא סיסמה) .
  4. לחץ על שמור .

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

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

    • url : הקישור העמוק להטמעה וכל מצב נוסף שיועבר. יש לרשום את הדומיין של הקישור ברשימת ה-Firebase Console של דומיינים מורשים, אותה ניתן למצוא על ידי מעבר לכרטיסייה שיטת כניסה (אימות -> שיטת כניסה). הקישור יפנה את המשתמש לכתובת האתר הזו אם האפליקציה לא מותקנת במכשיר שלו ולא ניתן היה להתקין את האפליקציה.
    • androidPackageName ו- IOSBundleId : האפליקציות שבהן ניתן להשתמש כאשר קישור הכניסה נפתח במכשיר אנדרואיד או אפל. למד עוד כיצד להגדיר את Firebase Dynamic Links לפתיחת קישורי פעולות דוא"ל באמצעות אפליקציות לנייד.
    • handleCodeInApp : מוגדר כ-true. יש להשלים תמיד את פעולת הכניסה באפליקציה בניגוד לפעולות דוא"ל אחרות מחוץ לתחום (איפוס סיסמה ואימותי דוא"ל). הסיבה לכך היא שבסוף הזרימה, המשתמש צפוי להיות מחובר ומצב האימות שלו יישאר באפליקציה.
    • dynamicLinkDomain : כאשר מוגדרים מספר דומיינים של קישורים דינמיים מותאמים אישית עבור פרויקט, ציין באיזה תחום להשתמש כאשר הקישור ייפתח באמצעות אפליקציה סלולרית שצוינה (לדוגמה, example.page.link ). אחרת הדומיין הראשון נבחר אוטומטית.

    Kotlin+KTX

    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+KTX

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

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

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

כמו כן ודא שאתה משתמש בכתובת URL של HTTPS בייצור כדי למנוע את הקישור שלך שיירטו על ידי שרתי מתווכים.

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

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

Firebase Auth משתמש ב-Firebase Dynamic Links בעת שליחת קישור שאמור להיפתח באפליקציה לנייד. כדי להשתמש בתכונה זו, יש להגדיר קישורים דינמיים ב-Firebase Console.

  1. הפעל קישורים דינמיים של Firebase:

    1. במסוף Firebase , פתח את הקטע קישורים דינמיים .
    2. אם עדיין לא הסכמתם לתנאי ה-Dynamic Links ויצרתם תחום Dynamic Links, עשו זאת כעת.

      אם כבר יצרת דומיין Dynamic Links, שים לב לזה. תחום קישורים דינמיים נראה בדרך כלל כמו הדוגמה הבאה:

      example.page.link

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

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

    1. על מנת לטפל בקישורים אלה מאפליקציית Android שלך, יש לציין את שם החבילה של Android בהגדרות הפרויקט של Firebase Console. בנוסף, יש לספק את SHA-1 ו-SHA-256 של אישור הבקשה.
    2. כעת, לאחר שהוספת תחום קישור דינמי והבטחת שאפליקציית Android שלך מוגדרת כהלכה, הקישור הדינמי יפנה מחדש לאפליקציה שלך, החל מפעילות המשגר.
    3. אם אתה רוצה שהקישור הדינמי יפנה מחדש לפעילות ספציפית, תצטרך להגדיר מסנן כוונות בקובץ AndroidManifest.xml שלך. ניתן לעשות זאת על ידי ציון תחום הקישור הדינמי שלך או מטפל בפעולות הדוא"ל במסנן הכוונות. כברירת מחדל, המטפל בפעולות הדוא"ל מתארח בדומיין כמו הדוגמה הבאה:
      PROJECT_ID.firebaseapp.com/
    4. אזהרות:
      1. אל תציין את כתובת האתר שהגדרת ב-actionCodeSettings במסנן הכוונות שלך.
      2. בעת יצירת תחום הקישור הדינמי שלך, ייתכן שיצרת גם קישור כתובת URL קצר. כתובת האתר הקצרה הזו לא תועבר; אל תגדיר את מסנן הכוונות שלך כדי לתפוס אותו עם תכונת android:pathPrefix . המשמעות היא שלא תוכל לתפוס קישורים דינמיים שונים בחלקים שונים של היישום שלך. עם זאת, אתה יכול לבדוק את פרמטר שאילתת mode בקישור כדי לראות איזו פעולה מנסה להתבצע, או להשתמש בשיטות SDK כגון isSignInWithEmailLink כדי לראות אם קישור שהאפליקציה שלך קיבלה עושה את מה שאתה רוצה.
    5. למידע נוסף על קבלת קישורים דינמיים, עיין בהוראות קבלת קישורים דינמיים ל-Android .

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

Kotlin+KTX

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+KTX

// 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+KTX

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

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

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

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

עיין בתיעוד על הגנת ספירת דוא"ל לפרטים נוספים.

הצעדים הבאים

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

  • באפליקציות שלך, תוכל לקבל את פרטי הפרופיל הבסיסיים של המשתמש מאובייקט FirebaseUser . ראה ניהול משתמשים .

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

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

כדי לצאת ממשתמש, התקשר ל- signOut :

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();