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

Możesz użyć uwierzytelniania Firebase, aby zalogować użytkownika, wysyłając mu e-maila zawierający link, który może kliknąć, aby się zalogować. W trakcie tego procesu użytkownik Adres e-mail również został zweryfikowany.

Logowanie się przez e-maila ma wiele zalet:

  • Rejestracja i logowanie przebiegają sprawnie.
  • Mniejsze ryzyko ponownego użycia hasła w różnych aplikacjach, co może zagrażać bezpieczeństwu nawet dobrze dobrane hasła.
  • Możliwość uwierzytelnienia użytkownika, a jednocześnie weryfikacja, czy użytkownik jest jest uprawnionym właścicielem adresu e-mail.
  • Aby się zalogować, użytkownik musi mieć tylko dostępne konto e-mail. Brak własności elementu Numer telefonu lub konto w mediach społecznościowych są wymagane.
  • Użytkownik może logować się bezpiecznie bez konieczności podawania (lub zapamiętania) co może być uciążliwe na urządzeniu mobilnym.
  • Istniejący użytkownik, który wcześniej zalogował się przy użyciu identyfikatora e-mail (hasła) lub sfederowanego) może przejść na wyższą wersję, aby logować się za pomocą samego adresu e-mail. Na przykład plik użytkownik, który nie pamięta hasła, może się zalogować bez konieczności resetować hasło.

Zanim zaczniesz

Konfigurowanie projektu na Androida

  1. Jeśli jeszcze nie masz tego za sobą, dodaj Firebase do swojego projektu na Androida.

  2. w pliku Gradle (na poziomie aplikacji) modułu, (zwykle <project>/<app-module>/build.gradle.kts lub <project>/<app-module>/build.gradle), dodaj zależność z biblioteką Firebase Authentication na Androida. Zalecamy użycie metody Firebase Android BoM aby kontrolować obsługę wersji biblioteki.

    Podczas konfigurowania usługi Firebase Authentication musisz też dodać do Twojej aplikacji przy użyciu pakietu SDK Usług Google Play.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.2.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.2.0")
    }

    Korzystając z narzędzia Firebase Android BoM, Twoja aplikacja zawsze używa zgodnych wersji bibliotek Firebase na Androida.

    (Wersja alternatywna) Dodaj zależności biblioteki Firebase bez użycia komponentu BoM

    Jeśli nie chcesz używać biblioteki Firebase BoM, musisz określić każdą wersję biblioteki Firebase w wierszu zależności.

    Pamiętaj, że jeśli używasz wielu bibliotek Firebase w swojej aplikacji, zalecamy korzystanie z BoM do zarządzania wersjami biblioteki. Dzięki temu wszystkie wersje są zgodne.

    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.0.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.2.0")
    }
    Szukasz modułu biblioteki korzystającego z usługi Kotlin? Zaczyna się za Październik 2023 r. (Firebase BoM 32.5.0) zarówno programiści Kotlin, jak i Java zależą od modułu biblioteki głównej (więcej informacji znajdziesz w Najczęstsze pytania na temat tej inicjatywy).

Aby zalogować użytkowników za pomocą linku w e-mailu, musisz najpierw włączyć dostawcę poczty e-mail Metoda logowania za pomocą linku wysłanego e-mailem do projektu Firebase:

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie.
  2. Na karcie Metoda logowania włącz dostawcę E-mail/hasła. Notatka że logowanie za pomocą adresu e-mail za pomocą linku wymaga włączenia logowania za pomocą adresu e-mail i hasła.
  3. W tej samej sekcji włącz logowanie się przy użyciu opcji Link w e-mailu (logowanie bez hasła). .
  4. Kliknij Zapisz.

Aby zainicjować proces uwierzytelniania, przekaż użytkownikowi interfejs, który prosi użytkownika o podanie adresu e-mail, a następnie sendSignInLinkToEmail, aby poprosić Firebase o wysłanie linku uwierzytelniającego do adres e-mail użytkownika.

  1. Utwórz ActionCodeSettings. który dostarcza Firebase instrukcje tworzenia . Ustaw wartości w tych polach:

    • url: precyzyjny link do umieszczenia i wszystkie dodatkowe stany do przekazania. Domena linku musi znajdować się na białej liście na liście w konsoli Firebase autoryzowane domeny, które można znaleźć na karcie Metoda logowania. (Uwierzytelnianie -> Metoda logowania). Link przekieruje użytkownika do strony ten adres URL, jeśli aplikacja nie jest zainstalowana na urządzeniu, a aplikacja nie została co można zainstalować.
    • androidPackageName i IOSBundleId: aplikacje do logowania jest otwarty na urządzeniu z systemem Android lub urządzeniu firmy Apple. Dowiedz się więcej o tym, Skonfiguruj Linki dynamiczne Firebase otwierać w aplikacjach mobilnych linki do działań w e-mailach.
    • handleCodeInApp: ustaw wartość prawda. Operacja logowania musi zawsze wykonane w aplikacji w przeciwieństwie do innych spoza zakresu działań związanych z e-mailami (hasło resetowanie urządzenia i potwierdzanie adresu e-mail). To dlatego, że na końcu cyklu użytkownik powinien być zalogowany, a jego stan uwierzytelniania utrzymywał się przez aplikację.
    • dynamicLinkDomain: gdy zdefiniowano wiele niestandardowych domen linków dynamicznych w projekcie, określ, który z nich ma być używany przy otwieraniu linku określoną aplikację mobilną (np. example.page.link). W przeciwnym razie Pierwsza domena jest wybierana automatycznie.

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

    Więcej informacji o ActionCodeSettings znajdziesz tutaj Stan udanego działania e-maili .

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

  3. Wyślij link uwierzytelniania na adres e-mail użytkownika i zapisz jego adres e-mail. w sytuacji, gdy użytkownik zaloguje się przez e-maila na tym samym urządzeniu.

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

Potencjalne problemy z bezpieczeństwem

Zapobieganie używaniu linku logowania do logowania się jako niezamierzony użytkownik lub po jego włączeniu niezamierzonym urządzeniem, Uwierzytelnianie Firebase wymaga podania adresu e-mail użytkownika podany podczas logowania. Aby można było się zalogować, ten adres e-mail musi odpowiadać adresowi, na który został pierwotnie wysłany link umożliwiający zalogowanie się.

Możesz usprawnić ten proces w przypadku użytkowników, którzy po kliknięciu linku logowania urządzenia, z którego użytkownik poprosi o link, zapisując swój adres e-mail lokalnie – dla za pomocą SharedPreferences – podczas wysyłania e-maila logowania. Następnie: użyj tego adresu, aby zakończyć proces. Nie przekazuj adresu e-mail użytkownika w parametrach adresu URL przekierowania i nie używaj go ponownie jako może to umożliwić wstrzykiwanie sesji.

Po zakończeniu logowania każdy wcześniej niezweryfikowany mechanizm logowania zostanie wyłączony. zostanie usunięte z konta użytkownika, a wszystkie istniejące sesje zostaną unieważnione. Na przykład jeśli ktoś wcześniej utworzył niezweryfikowane konto z tym samym adres e-mail i hasło zostaną usunięte, aby zapobiec Użytkownik podszywający się pod Ciebie, który zgłosił prawo własności i utworzył niezweryfikowane konto z zaloguj się ponownie przy użyciu niezweryfikowanego adresu e-mail i hasła.

Upewnij się też, że używasz adresu URL HTTPS w wersji produkcyjnej. Dzięki temu link nie będzie potencjalnie przechwycone przez serwery pośrednie.

Logowanie się w aplikacji na Androida

Uwierzytelnianie Firebase używa Linków dynamicznych Firebase do wysyłania linku e-mail do urządzenia mobilnego. W celu zalogowania się za pomocą aplikacji mobilnej aplikacja należy skonfigurować, aby wykrywać przychodzący link aplikacji, przeanalizować użyj precyzyjnego linku, a potem zaloguj się.

Uwierzytelnianie Firebase używa Linków dynamicznych Firebase do wysyłania który powinien być otwierany w aplikacji mobilnej. Aby korzystać z Linki dynamiczne muszą być skonfigurowane w konsoli Firebase.

  1. Włącz Linki dynamiczne Firebase:

    1. W konsoli Firebase otwórz sekcję Dynamic Links.
    2. Jeśli warunki usługi Dynamic Links nie zostały jeszcze przez Ciebie zaakceptowane, a Dynamic Links nie zostało utworzone domeny, zrób to teraz.

      Jeśli masz już utworzoną domenę Dynamic Links, zanotuj ją. Dynamic Links domena zwykle wygląda tak:

      example.page.link

      Ta wartość będzie potrzebna podczas konfigurowania aplikacji na Apple lub Androida przechwytywać link przychodzący.

  2. Konfigurowanie aplikacji na Androida:

    1. Aby obsługiwać te linki z aplikacji na Androida, Nazwę pakietu na Androida trzeba określić w konsoli Firebase ustawieniach projektu. Dodatkowo SHA-1 i SHA-256 aplikacji i dostarczyć certyfikat.
    2. Po dodaniu domeny linku dynamicznego Aplikacja na Androida jest skonfigurowana prawidłowo, link dynamiczny przekierowuje na adres do aplikacji, zaczynając od działań w programie uruchamiającym.
    3. Jeśli chcesz, by link dynamiczny przekierowywał do określonej aktywności, będzie musiała skonfigurować filtr intencji w pliku AndroidManifest.xml. . W tym celu możesz podać domenę linku dynamicznego lub z modułu obsługi działań e-mail w filtrze intencji. Domyślnie adres e-mail moduł obsługi działań jest hostowany w domenie jak w tym przykładzie:
      PROJECT_ID.firebaseapp.com/
    4. Uwagi:
      1. Nie określaj adresu URL ustawionego w sekcji actionCodeSettings w sekcji filtr intencji.
      2. Przy tworzeniu domeny linku dynamicznego mogłeś też utworzyć przez krótki URL. Ten krótki URL nie zostanie przekazany. nie skonfigurować filtr intencji w taki sposób, aby wyłapywał go za pomocą android:pathPrefix. Oznacza to, że nie wychwytują różnych linków dynamicznych w różnych częściach Twojej aplikacji. Możesz jednak sprawdzić parametr zapytania mode w linku, by zobaczyć, jaka operacja jest wykonywana. użyj metod SDK, takich jak isSignInWithEmailLink, by sprawdzić, link do aplikacji umożliwia wykonanie tego, co chcesz.
    5. Więcej informacji o otrzymywaniu linków dynamicznych znajdziesz tutaj: Instrukcje dotyczące Linków dynamicznych na Androidzie.

Po otrzymaniu linku w sposób opisany powyżej sprawdź, czy jest on przeznaczony do e-maili. uwierzytelnienie połączenia i dokończenie logowania.

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

Aby dowiedzieć się więcej o obsłudze logowania za pomocą linku e-mail na urządzeniu Apple aplikacji znajdziesz w przewodniku po platformach Apple.

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

Możesz też powiązać tę metodę uwierzytelniania z istniejącym użytkownikiem. Przykład: użytkownik został wcześniej uwierzytelniony u innego dostawcy, np. przy użyciu numeru telefonu; mogą dodać tę metodę logowania do swojego istniejącego konta.

Różnica będzie widoczna w drugiej połowie operacji:

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

W ten sposób można też ponownie uwierzytelnić użytkownika korzystającego z linku e-mail przed uruchomieniem poufnej operacji.

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

Ponieważ przepływ może jednak skończyć się na innym urządzeniu, na którym pierwotny użytkownik Użytkownik nie jest zalogowany, ten proces mógł nie zostać ukończony. W takim przypadku błąd może ma być wyświetlana użytkownikowi, aby zmusić go do otwarcia linku na tym samym urządzeniu. Niektóre stan można przekazać w linku w celu podania informacji o typie operacji oraz identyfikator UID użytkownika.

Jeśli Twój projekt został utworzony 15 września 2023 r. lub później, lista adresów e-mail ochrona jest domyślnie włączona. Ta funkcja zwiększa bezpieczeństwo kont użytkowników projektu, ale wyłącza fetchSignInMethodsForEmail() Metoda, którą mieliśmy wcześniej zalecać do implementacji przepływów skoncentrowanych na identyfikatorze.

Chociaż możesz wyłączyć ochronę wyliczania adresów e-mail w projekcie, takiego działania.

Zapoznaj się z dokumentacją dotyczącą ochrony przed wyliczeniem adresów e-mail .

Dalsze kroki

Gdy użytkownik zaloguje się po raz pierwszy, tworzone jest nowe konto użytkownika. powiązane z danymi logowania, czyli z nazwą użytkownika, hasłem i numerem telefonu, numer telefonu lub informacje o dostawcy uwierzytelniania – użytkownik zalogowany. Ten nowy jest przechowywane w ramach projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się loguje.

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

  • Na liście Firebase Realtime Database i Cloud Storage regułami zabezpieczeń, pobierz ze zmiennej auth unikalny identyfikator zalogowanego użytkownika, i używać ich do kontrolowania, do jakich danych użytkownik ma dostęp.

Możesz zezwolić użytkownikom na logowanie się w aplikacji przy użyciu wielokrotnego uwierzytelniania. dostawców, łącząc dane logowania dostawcy uwierzytelniania z istniejącego konta użytkownika.

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

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();