Uwierzytelnianie w Firebase za pomocą linku e-mail na Androidzie

Możesz zalogować użytkownika za pomocą Firebase Authentication, wysyłając mu e-maila z linkiem, który może kliknąć, aby się zalogować. W tym procesie weryfikowany jest też adres e-mail użytkownika.

Logowanie za pomocą adresu e-mail ma wiele korzyści:

  • Bezproblemowa rejestracja i logowanie.
  • Mniejsze ryzyko ponownego użycia haseł w różnych aplikacjach, co może osłabić bezpieczeństwo nawet dobrze dobranych haseł.
  • Możliwość uwierzytelniania użytkownika przy jednoczesnej weryfikacji, czy jest on prawowitym właścicielem adresu e-mail.
  • Aby się zalogować, użytkownik potrzebuje tylko dostępnego konta e-mail. Nie musisz być właścicielem numeru telefonu ani konta w mediach społecznościowych.
  • Użytkownik może bezpiecznie zalogować się bez konieczności podawania (lub zapamiętywania) hasła, co może być uciążliwe na urządzeniu mobilnym.
  • Dotychczasowy użytkownik, który wcześniej logował się za pomocą identyfikatora e-mail (hasła lub logowania sfederowanego), może przejść na logowanie się tylko przy użyciu adresu e-mail. Na przykład użytkownik, który zapomniał hasła, może się zalogować bez konieczności jego resetowania.

Zanim zaczniesz

Konfigurowanie projektu aplikacji na Androida

  1. Jeśli nie korzystasz jeszcze z tej usługi, dodaj Firebase do projektu aplikacji na Androida.

  2. W pliku Gradle modułu (na poziomie aplikacji) (zwykle <project>/<app-module>/build.gradle.kts lub <project>/<app-module>/build.gradle) dodaj zależność z biblioteką Firebase Authentication na Androida. Zalecamy używanie Firebase Android BoM do kontrolowania obsługi wersji biblioteki.

    W ramach konfiguracji Firebase Authentication musisz też dodać do aplikacji pakiet SDK usług Google Play.

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

    Gdy korzystamy z Firebase Android BoM, aplikacja zawsze używa zgodnych wersji bibliotek Firebase na Androida.

    (Alternatywnie)  Dodaj zależności biblioteki Firebase bez używania BoM

    Jeśli nie zdecydujesz się na użycie Firebase BoM, musisz określić wersję każdej biblioteki Firebase w wierszu zależności.

    Pamiętaj, że jeśli w aplikacji używasz kilku bibliotek Firebase, zdecydowanie zalecamy używanie BoM do zarządzania wersjami bibliotek, co zapewnia zgodność wszystkich wersji.

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

Włączanie logowania za pomocą linku e-mail w projekcie w Firebase

Aby logować użytkowników za pomocą linku w e-mailu, musisz najpierw włączyć dostawcę poczty e-mail i metodę logowania za pomocą linku w e-mailu w projekcie w Firebase:

  1. W konsoli Firebase otwórz Bezpieczeństwo > Uwierzytelnianie.

  2. Na karcie Metoda logowania włącz dostawcę logowania E-mail/hasło. Pamiętaj, że aby korzystać z logowania za pomocą linku w e-mailu, musisz włączyć logowanie za pomocą adresu e-mail i hasła.

  3. W tej samej sekcji włącz dostawcę tożsamości Link w e-mailu (logowanie bez hasła).

  4. Kliknij Zapisz.

Aby rozpocząć proces uwierzytelniania, wyświetl użytkownikowi interfejs, w którym będzie on proszony o podanie adresu e-mail, a następnie wywołaj funkcję sendSignInLinkToEmail, aby poprosić Firebase o wysłanie linku do uwierzytelniania na adres e-mail użytkownika.

  1. Utwórz obiekt ActionCodeSettings, który zawiera instrukcje dla Firebase dotyczące tworzenia linku w e-mailu. Ustaw wartości w tych polach:

    • url: precyzyjny link do umieszczenia i wszelkie dodatkowe informacje o stanie, które mają zostać przekazane. Jeśli jeszcze tego nie zrobiono, dodaj domenę linku do listy autoryzowanych domen:

      1. W konsoli Firebase otwórz Zabezpieczenia > Uwierzytelnianie > karta Ustawienia.

      2. W sekcji Autoryzowane domeny kliknij Dodaj domenę i dodaj domenę linku.

      Jeśli aplikacja nie jest zainstalowana na urządzeniu użytkownika i nie można jej zainstalować, link przekieruje go na ten adres URL.

    • androidPackageName i iOSBundleId: pomaga Firebase Authentication określić, czy ma utworzyć link tylko do internetu czy link mobilny, który zostanie otwarty na urządzeniu z Androidem lub Apple.
    • handleCodeInApp: ustaw na wartość „true”. Proces logowania musi zawsze być przeprowadzany w aplikacji, w przeciwieństwie do innych działań wykonywanych poza pasmem za pomocą e-maila (resetowanie hasła i weryfikacja adresu e-mail). Dzieje się tak, ponieważ na końcu procesu użytkownik powinien być zalogowany, a jego stan uwierzytelniania powinien być zachowany w aplikacji.
    • linkDomain: Jeśli w projekcie zdefiniowano niestandardowe domeny linków Hosting, określ, której z nich należy użyć, gdy link ma być otwierany przez konkretną aplikację mobilną. W przeciwnym razie automatycznie zostanie wybrana domena domyślna (np. PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: wycofano. Nie podawaj tego parametru.

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

    Więcej informacji o ActionCodeSettings znajdziesz w sekcji Przekazywanie stanu w działaniach związanych z e-mailami.

  2. Poproś użytkownika o podanie adresu e-mail.

  3. Wyślij link uwierzytelniający na adres e-mail użytkownika i zapisz ten adres na wypadek, gdyby użytkownik dokończył logowanie przez e-mail na tym samym urządzeniu.

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

Potencjalne problemy z bezpieczeństwem

Aby zapobiec użyciu linku do logowania w celu zalogowania się jako nieodpowiedni użytkownik lub na nieodpowiednim urządzeniu, Firebase Authentication wymaga podania adresu e-mail użytkownika podczas procesu logowania. Aby logowanie się powiodło, ten adres e-mail musi być zgodny z adresem, na który pierwotnie został wysłany link do logowania.

Możesz uprościć ten proces dla użytkowników, którzy otwierają link do logowania na tym samym urządzeniu, na którym go zażądali. W tym celu zapisz lokalnie ich adres e-mail – na przykład za pomocą SharedPreferences – gdy wyślesz e-maila z linkiem do logowania. Następnie użyj tego adresu, aby dokończyć proces. Nie przekazuj adresu e-mail użytkownika w parametrach adresu URL przekierowania i nie używaj go ponownie, ponieważ może to umożliwić wstrzykiwanie sesji.

Po zakończeniu logowania wszystkie poprzednie niezweryfikowane mechanizmy logowania zostaną usunięte z konta użytkownika, a wszystkie dotychczasowe sesje zostaną unieważnione. Jeśli na przykład ktoś wcześniej utworzył niezweryfikowane konto z tym samym adresem e-mail i hasłem, hasło użytkownika zostanie usunięte, aby uniemożliwić podszywającemu się pod niego użytkownikowi, który zgłosił własność i utworzył to niezweryfikowane konto, ponowne zalogowanie się przy użyciu niezweryfikowanego adresu e-mail i hasła.

W środowisku produkcyjnym używaj adresu URL HTTPS, aby uniknąć potencjalnego przechwycenia linku przez serwery pośredniczące.

Kończenie logowania w aplikacji na Androida

Firebase Authentication używa Firebase Hosting, aby wysłać link do e-maila na urządzenie mobilne. Aby dokończyć logowanie za pomocą aplikacji mobilnej, musi ona być skonfigurowana tak, aby wykrywać przychodzący link do aplikacji, analizować bazowy precyzyjny link, a następnie dokończyć logowanie. Więcej informacji znajdziesz w dokumentacji linków aplikacji na Androida.

Skonfiguruj funkcję Firebase Hosting

Firebase Authentication używa domen Firebase Hosting podczas tworzenia i wysyłania linku, który ma być otwierany w aplikacji mobilnej. Domyślna Firebase Hosting domena została już skonfigurowana.

  1. Skonfiguruj domeny Firebase Hosting:

    W konsoli Firebase otwórz Hosting i usługi bezserwerowe > Hosting.

    • Jeśli chcesz użyć domyślnej domeny w przypadku linku w e-mailu, który otwiera się w aplikacjach mobilnych, przejdź do domyślnej witryny i zanotuj domyślną domenę Hosting. Domyślna domena Hosting zwykle wygląda tak:PROJECT_ID.firebaseapp.com.

      Będzie on potrzebny podczas konfigurowania aplikacji do przechwytywania przychodzącego linku.

    • Jeśli chcesz użyć niestandardowej domeny w przypadku linku do e-maila, możesz zarejestrować ją w Firebase Hosting i użyć jej jako domeny linku.

  2. Konfigurowanie aplikacji na Androida:

    Aby obsługiwać te linki w aplikacji na Androida, musisz podać nazwę pakietu aplikacji w Firebaseustawieniach projektu w konsoli. Dodatkowo należy podać SHA-1 i SHA-256 certyfikatu aplikacji.

    Jeśli chcesz, aby te linki przekierowywały do konkretnego działania, musisz skonfigurować filtr intencji w pliku AndroidManifest.xml. Filtr intencji powinien przechwytywać linki do e-maili w Twojej domenie. W 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>
    

    Gdy użytkownicy otworzą link do hostingu ze ścieżką /__/auth/links oraz schematem i hostem, które określisz, Twoja aplikacja uruchomi działanie z tym filtrem intencji, aby obsłużyć link.

Po otrzymaniu linku w sposób opisany powyżej sprawdź, czy służy on do uwierzytelniania za pomocą linku w e-mailu, i zaloguj się.

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

Więcej informacji o obsłudze logowania za pomocą linku w e-mailu w aplikacji Apple znajdziesz w przewodniku po platformach Apple.

Aby dowiedzieć się, jak obsługiwać logowanie za pomocą linku w e-mailu w aplikacji internetowej, zapoznaj się z przewodnikiem po internecie.

Możesz też połączyć tę metodę uwierzytelniania z istniejącym użytkownikiem. Na przykład użytkownik, który wcześniej uwierzytelnił się u innego dostawcy, np. za pomocą numeru telefonu, może dodać tę metodę logowania do swojego obecnego konta.

Różnica wystąpi w drugiej połowie operacji:

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

Można go też użyć do ponownego uwierzytelnienia użytkownika linku e-mail przed wykonaniem operacji wymagającej szczególnej ochrony.

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

Jednak proces może zakończyć się na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany, więc może nie zostać ukończony. W takim przypadku użytkownikowi może zostać wyświetlony błąd, który zmusi go do otwarcia linku na tym samym urządzeniu. W linku można przekazać pewien stan, aby podać informacje o typie operacji i identyfikatorze użytkownika.

Uwierzytelnianie za pomocą linku w e-mailu korzystało wcześniej z Firebase Dynamic Links, które zostanie wyłączone 25 sierpnia 2025 r.

Opublikowaliśmy alternatywne rozwiązanie w Firebase Authenticationpakiecie SDK na Androida w wersji 23.2.0 lub nowszej i w Firebase BoMwersji 33.9.0 lub nowszej.

Jeśli aplikacja korzysta ze starych linków, przenieś ją do nowego systemu opartego na Firebase Hosting.

Jeśli projekt został utworzony 15 września 2023 r. lub później, ochrona przed wyliczaniem adresów e-mail jest domyślnie włączona. Ta funkcja zwiększa bezpieczeństwo kont użytkowników projektu, ale wyłącza metodę fetchSignInMethodsForEmail(), którą wcześniej zalecaliśmy do implementowania przepływów opartych na identyfikatorze.

Chociaż możesz wyłączyć ochronę przed wyliczaniem adresów e-mail w swoim projekcie, nie zalecamy tego.

Więcej informacji znajdziesz w dokumentacji dotyczącej ochrony przed wyliczaniem adresów e-mail.

Dalsze kroki

Po pierwszym zalogowaniu się użytkownika tworzone jest nowe konto użytkownika, które jest powiązane z danymi logowania, czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania, za pomocą których użytkownik się zalogował. To nowe konto jest przechowywane w ramach projektu w Firebase i może służyć do identyfikowania użytkownika we wszystkich aplikacjach w projekcie, niezależnie od sposobu logowania.

  • W aplikacjach możesz pobierać podstawowe informacje o profilu użytkownika z obiektu FirebaseUser. Zobacz Zarządzanie użytkownikami.

  • W Firebase Realtime Database i Cloud Storage regułach bezpieczeństwa możesz pobrać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i użyć go do kontrolowania, do jakich danych użytkownik może mieć dostęp.

Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą wielu dostawców uwierzytelniania, łącząc dane logowania dostawcy uwierzytelniania z istniejącym kontem użytkownika.

Aby wylogować użytkownika, wywołaj funkcję signOut:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();