Authentifizieren Sie sich bei Firebase über einen E-Mail-Link in Android

Sie können Firebase Authentication verwenden, um einen Benutzer anzumelden, indem Sie ihm eine E-Mail mit einem Link senden, auf den er zum Anmelden klicken kann. Dabei wird auch die E-Mail-Adresse des Benutzers verifiziert.

Die Anmeldung per E-Mail bietet zahlreiche Vorteile:

  • Reibungsarme Anmeldung und Anmeldung.
  • Geringeres Risiko der Wiederverwendung von Kennwörtern über Anwendungen hinweg, was die Sicherheit selbst gut ausgewählter Kennwörter untergraben kann.
  • Die Möglichkeit, einen Benutzer zu authentifizieren und gleichzeitig zu überprüfen, ob der Benutzer der rechtmäßige Besitzer einer E-Mail-Adresse ist.
  • Ein Benutzer benötigt nur ein zugängliches E-Mail-Konto, um sich anzumelden. Es ist kein Besitz einer Telefonnummer oder eines Social-Media-Kontos erforderlich.
  • Ein Benutzer kann sich sicher anmelden, ohne ein Passwort eingeben (oder sich merken) zu müssen, was auf einem Mobilgerät umständlich sein kann.
  • Ein vorhandener Benutzer, der sich zuvor mit einer E-Mail-Kennung (Passwort oder Verbund) angemeldet hat, kann aktualisiert werden, um sich nur mit der E-Mail anzumelden. So kann sich beispielsweise ein Benutzer, der sein Kennwort vergessen hat, trotzdem anmelden, ohne sein Kennwort zurücksetzen zu müssen.

Bevor Sie beginnen

Richten Sie Ihr Android-Projekt ein

  1. Wenn Sie nicht bereits haben, fügen Sie Firebase zu dem Android - Projekt .

  2. Mit Hilfe der Firebase Android BoM , erklärt die Abhängigkeit für die Firebase Authentifizierung Android - Bibliothek in Ihrem Modul (app-Ebene) Gradle Datei ( in der Regel app/build.gradle ).

    Als Teil der Einrichtung von Firebase Authentication müssen Sie außerdem das SDK für die Google Play-Dienste zu Ihrer App hinzufügen.

    Java

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.4')
    
        // Declare 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 declare the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.0.1'
    }

    Durch die Verwendung des Firebase Android BoM werden, Ihre App immer kompatible Versionen der Firebase Android - Bibliotheken verwenden.

    (Alternative) Deklarieren Firebase Bibliothek Abhängigkeiten , ohne die BoM mit

    Wenn Sie die Firebase-Stückliste nicht verwenden möchten, müssen Sie jede Firebase-Bibliotheksversion in ihrer Abhängigkeitszeile angeben.

    Beachten Sie, dass , wenn Sie mehrere Firebase Bibliotheken in Ihrer Anwendung verwenden wir mit der BoM empfehlen Bibliothek Versionen zu verwalten, die sicherstellt , dass alle Versionen kompatibel sind.

    dependencies {
        // Declare 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:21.0.1'
    // Also declare the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.0.1'
    }

    Kotlin+KTX

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.4')
    
        // Declare 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-ktx'
    // Also declare the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.0.1'
    }

    Durch die Verwendung des Firebase Android BoM werden, Ihre App immer kompatible Versionen der Firebase Android - Bibliotheken verwenden.

    (Alternative) Deklarieren Firebase Bibliothek Abhängigkeiten , ohne die BoM mit

    Wenn Sie die Firebase-Stückliste nicht verwenden möchten, müssen Sie jede Firebase-Bibliotheksversion in ihrer Abhängigkeitszeile angeben.

    Beachten Sie, dass , wenn Sie mehrere Firebase Bibliotheken in Ihrer Anwendung verwenden wir mit der BoM empfehlen Bibliothek Versionen zu verwalten, die sicherstellt , dass alle Versionen kompatibel sind.

    dependencies {
        // Declare 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-ktx:21.0.1'
    // Also declare the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.0.1'
    }

Um Benutzer per E-Mail-Link anzumelden, müssen Sie zunächst den E-Mail-Anbieter und die E-Mail-Link-Anmeldemethode für Ihr Firebase-Projekt aktivieren:

  1. In der Firebase Konsole , öffnen Sie den Abschnitt Auth.
  2. Auf dem Anmelden Methode Registerkarte, aktivieren Sie den E - Mail / Passwort - Anbieter. Beachten Sie, dass die E-Mail-/Passwort-Anmeldung aktiviert sein muss, um die E-Mail-Link-Anmeldung zu verwenden.
  3. Im selben Abschnitt aktiviert E - Mail - Link ( ohne Passwort-Anmeldung) Anmelde-Verfahren.
  4. Klicken Sie auf Speichern.

Zur Initiierung der Authentifizierungsablauf stellen dem Benutzer eine Schnittstelle , die Anweisungen , um den Benutzer zu geben , ihre E - Mail - Adresse und dann rufen sendSignInLinkToEmail zu fordern , dass die Authentifizierungsfirebase Verbindung des Benutzers E - Mail senden.

  1. Konstruieren Sie das ActionCodeSettings Objekt, das Firebase mit Anweisungen liefert , wie der E - Mail - Link zu konstruieren. Legen Sie die folgenden Felder fest:

    • url : Der Deep - Link zu einbetten und jedem weiteren Zustand zu übergeben entlang. Die Domain des Links muss in der Firebase Console-Liste der autorisierten Domains auf die Whitelist gesetzt werden, die auf der Registerkarte Anmeldemethode (Authentifizierung -> Anmeldemethode) zu finden ist. Der Link leitet den Benutzer zu dieser URL um, wenn die App nicht auf seinem Gerät installiert ist und die App nicht installiert werden konnte.
    • androidPackageName und IOSBundleId : Die Apps zu verwenden , wenn die Anmelde-Link auf einem Android oder Apple - Gerät geöffnet wird. Erfahren Sie mehr darüber , wie auf Firebase dynamische Links konfigurieren zu öffnen E - Mail - Aktion Verbindungen über mobile Anwendungen.
    • handleCodeInApp : Wird auf true gesetzt. Der Anmeldevorgang muss im Gegensatz zu anderen Out-of-Band-E-Mail-Aktionen (Passwortrücksetzung und E-Mail-Verifizierungen) immer in der App durchgeführt werden. Dies liegt daran, dass am Ende des Flows erwartet wird, dass der Benutzer angemeldet ist und sein Authentifizierungsstatus in der App beibehalten wird.
    • dynamicLinkDomain : Wenn mehrere benutzerdefinierte Dynamic Link - Domänen sind für ein Projekt definiert ist , anzugeben , welche eine verwenden , wenn die Verbindung über eine spezifizierte mobile app geöffnet werden soll (beispielsweise example.page.link ). Andernfalls wird automatisch die erste Domäne ausgewählt.

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

    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 */)
    }

    Um mehr zu erfahren über ActionCodeSettings, beziehen sich auf die Übergabe Staat in E - Mail - Aktionen Abschnitt.

  2. Fragen Sie den Benutzer nach seiner E-Mail.

  3. Senden Sie den Authentifizierungslink an die E-Mail des Benutzers und speichern Sie die E-Mail des Benutzers für den Fall, dass der Benutzer die E-Mail-Anmeldung auf demselben Gerät abschließt.

    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.");
                    }
                }
            });

    Kotlin+KTX

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Email sent.")
                }
            }

Sicherheitsbedenken

Um zu verhindern, dass ein Anmeldelink verwendet wird, um sich als unbeabsichtigter Benutzer oder auf einem unbeabsichtigten Gerät anzumelden, erfordert Firebase Auth die Angabe der E-Mail-Adresse des Benutzers beim Abschließen des Anmeldevorgangs. Damit die Anmeldung erfolgreich ist, muss diese E-Mail-Adresse mit der Adresse übereinstimmen, an die der Anmeldelink ursprünglich gesendet wurde.

Sie können diesen Ablauf für Benutzer optimieren, die den Anmeldelink auf demselben Gerät öffnen, auf dem sie den Link anfordern, indem Sie ihre E-Mail-Adresse lokal speichern – beispielsweise mithilfe von SharedPreferences –, wenn Sie die Anmelde-E-Mail senden. Verwenden Sie dann diese Adresse, um den Flow abzuschließen. Übergeben Sie die E-Mail des Benutzers nicht in den Umleitungs-URL-Parametern und verwenden Sie sie erneut, da dies Sitzungsinjektionen ermöglichen kann.

Nach Abschluss der Anmeldung werden alle vorherigen nicht überprüften Anmeldemechanismen vom Benutzer entfernt und alle vorhandenen Sitzungen werden ungültig gemacht. Wenn beispielsweise jemand zuvor ein unbestätigtes Konto mit derselben E-Mail-Adresse und demselben Kennwort erstellt hat, wird das Kennwort des Benutzers entfernt, um zu verhindern, dass sich der Nachahmer, der die Inhaberschaft beansprucht und dieses unbestätigte Konto erstellt hat, erneut mit der unbestätigten E-Mail-Adresse und dem unbestätigten Kennwort anmeldet.

Stellen Sie außerdem sicher, dass Sie in der Produktion eine HTTPS-URL verwenden, um zu vermeiden, dass Ihr Link möglicherweise von zwischengeschalteten Servern abgefangen wird.

Abschließen der Anmeldung in einer Android-App

Firebase Authentication verwendet Firebase Dynamic Links, um den E-Mail-Link an ein Mobilgerät zu senden. Um die Anmeldung über die mobile Anwendung abzuschließen, muss die Anwendung so konfiguriert werden, dass sie den eingehenden Anwendungslink erkennt, den zugrunde liegenden Deeplink parst und dann die Anmeldung abschließt.

Firebase Auth verwendet Firebase dynamische Links , wenn Sie einen Link zu senden , die in einer mobilen Anwendung geöffnet werden soll. Um diese Funktion zu nutzen, dynamische Links müssen in der Konsole Firebase konfiguriert werden.

  1. Dynamische Firebase-Links aktivieren:

    1. In der Firebase Konsole öffnet Abschnitt des dynamischen Links.
    2. Wenn Sie die Bedingungen für Dynamic Links noch nicht akzeptiert und eine Dynamic Links-Domäne erstellt haben, tun Sie dies jetzt.

      Wenn Sie bereits eine Dynamic Links-Domäne erstellt haben, notieren Sie sich diese. Eine Dynamic Links-Domäne sieht normalerweise wie im folgenden Beispiel aus:

      example.page.link

      Sie benötigen diesen Wert, wenn Sie Ihre Apple- oder Android-App konfigurieren, um den eingehenden Link abzufangen.

  2. Android-Anwendungen konfigurieren:

    1. Um diese Links von Ihrer Android-Anwendung aus verarbeiten zu können, muss der Android-Paketname in den Projekteinstellungen der Firebase Console angegeben werden. Außerdem müssen SHA-1 und SHA-256 des Antragszertifikats vorgelegt werden.
    2. Nachdem Sie nun eine dynamische Linkdomäne hinzugefügt und sichergestellt haben, dass Ihre Android-App richtig konfiguriert ist, leitet der dynamische Link ab der Launcher-Aktivität zu Ihrer Anwendung um.
    3. Wenn Sie den dynamischen Link zu Umleitung auf eine spezifische Aktivität möchten, müssen Sie einen Intent - Filter in AndroidManifest.xml Datei konfigurieren. Dazu können Sie entweder Ihre dynamische Linkdomäne oder den E-Mail-Aktionshandler im Intent-Filter angeben. Standardmäßig wird der E - Mail - Action - Handler auf einer Domain wie im folgende Beispiel gehostet:
      PROJECT_ID.firebaseapp.com/
    4. Vorbehalte:
      1. Geben Sie nicht die URL an, die Sie in den actionCodeSettings in Ihrem Absichtsfilter festgelegt haben.
      2. Beim Erstellen Ihrer Dynamic Link-Domain haben Sie möglicherweise auch einen kurzen URL-Link erstellt. Diese kurze URL wird nicht weitergegeben; nicht konfigurieren Ihre Absicht Filter es mit einem fangen android:pathPrefix Attribut. Dies bedeutet, dass Sie nicht in der Lage sein werden, unterschiedliche dynamische Links in verschiedenen Teilen Ihrer Anwendung abzufangen. Sie können jedoch den mode Abfrageparameter in dem Link , um zu sehen , welche Operation durchgeführt werden soll versucht, oder die Verwendung SDK Methoden wie isSignInWithEmailLink , um zu sehen , ob ein Link , dass Ihr App erhalten hat , das tut , was Sie wollen.
    5. Weitere Informationen über dynamische Links Empfang finden Sie auf Android dynamische Links Anweisungen empfangen .

Nachdem Sie den Link wie oben beschrieben erhalten haben, überprüfen Sie, ob er für die E-Mail-Link-Authentifizierung bestimmt ist, und schließen Sie die Anmeldung ab.

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+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)
                }
            }
}

Um mehr zu erfahren, wie man behandelt Sign-in mit E - Mail - Link in einer Apple - Anwendung finden Sie auf die Apple - Plattformen Führung .

Um zu erfahren , wie zu handhaben -Anmeldung mit E - Mail - Link in einer Web - Anwendung finden Sie im Web Guide .

Sie können diese Authentifizierungsmethode auch mit einem vorhandenen Benutzer verknüpfen. Beispielsweise kann ein Benutzer, der sich zuvor bei einem anderen Anbieter wie einer Telefonnummer authentifiziert hat, diese Anmeldemethode zu seinem bestehenden Konto hinzufügen.

Der Unterschied wäre in der zweiten Hälfte der Operation:

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)

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

Dies kann auch verwendet werden, um einen E-Mail-Link-Benutzer erneut zu authentifizieren, bevor ein vertraulicher Vorgang ausgeführt wird.

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

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

Da der Flow jedoch auf einem anderen Gerät landen kann, auf dem der ursprüngliche Benutzer nicht angemeldet war, wird dieser Flow möglicherweise nicht abgeschlossen. In diesem Fall kann dem Benutzer ein Fehler angezeigt werden, um ihn zu zwingen, den Link auf demselben Gerät zu öffnen. Im Link kann ein Status übergeben werden, um Informationen über die Art des Vorgangs und die Benutzer-UID bereitzustellen.

Im Fall unterstützen Sie sowohl Passwort und Link-basierte Anmeldung mit E - Mail, die Methode der Zeichen in einem Passwort / link Benutzer zu unterscheiden, verwenden fetchSignInMethodsForEmail . Dies ist nützlich für Identifier-First-Flows, bei denen der Benutzer zuerst aufgefordert wird, seine E-Mail-Adresse anzugeben und dann die Anmeldemethode angezeigt wird:

Java

auth.fetchSignInMethodsForEmail(email)
        .addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
            @Override
            public void onComplete(@NonNull Task<SignInMethodQueryResult> task) {
                if (task.isSuccessful()) {
                    SignInMethodQueryResult result = task.getResult();
                    List<String> signInMethods = result.getSignInMethods();
                    if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                        // User can sign in with email/password
                    } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                        // User can sign in with email/link
                    }
                } else {
                    Log.e(TAG, "Error getting sign in methods for user", task.getException());
                }
            }
        });

Kotlin+KTX

Firebase.auth.fetchSignInMethodsForEmail(email)
        .addOnSuccessListener { result ->
            val signInMethods = result.signInMethods!!
            if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                // User can sign in with email/password
            } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                // User can sign in with email/link
            }
        }
        .addOnFailureListener { exception ->
            Log.e(TAG, "Error getting sign in methods for user", exception)
        }

Wie oben E - Mail / Passwort und E - Mail / link beschrieben ist der gleiche betrachtet EmailAuthProvider (gleiche PROVIDER_ID ) mit verschiedenen Methoden der Anmeldung.

Nächste Schritte

Nachdem sich ein Benutzer zum ersten Mal anmeldet, wird ein neues Benutzerkonto erstellt und mit den Anmeldeinformationen – d. h. Benutzername und Kennwort, Telefonnummer oder Authentifizierungsanbieterinformationen – verknüpft, mit denen sich der Benutzer angemeldet hat. Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Benutzer in jeder App in Ihrem Projekt zu identifizieren, unabhängig davon, wie sich der Benutzer anmeldet.

  • In Ihren Anwendungen können Sie die Benutzerprofilgrundinformationen aus dem bekommen FirebaseUser Objekt. Siehe Benutzer verwalten .

  • In Ihrer Datenbank und Firebase Realtime Cloud Storage Sicherheitsregeln , können Sie die angemeldeten Nutzer die eindeutige Benutzer - ID aus der bekommen auth Variable, und es verwenden , um steuern kann ein Benutzer Zugriff , welche Daten.

Sie können Benutzer erlauben , durch mehrere Authentifizierungsanbieter anmelden, um Ihre App Verknüpfung Auth - Provider - Anmeldeinformationen zu einem vorhandenen Benutzerkonto.

Um einen Benutzer abzumelden, rufen signOut :

Java

FirebaseAuth.getInstance().signOut();

Kotlin+KTX

Firebase.auth.signOut()