Możesz użyć uwierzytelniania Firebase, aby zalogować użytkownika, wysyłając mu wiadomość e-mail zawierającą link, który może kliknąć, aby się zalogować. Podczas tego procesu weryfikowany jest również adres e-mail użytkownika.
Logowanie przez e-mail ma wiele zalet:
- Bezproblemowa rejestracja i logowanie.
- Mniejsze ryzyko ponownego użycia hasła w różnych aplikacjach, co może podważyć bezpieczeństwo nawet dobrze dobranych haseł.
- Możliwość uwierzytelnienia użytkownika przy jednoczesnym sprawdzeniu, czy użytkownik jest prawowitym właścicielem adresu e-mail.
- Użytkownik potrzebuje tylko dostępnego konta e-mail, aby się zalogować. Nie jest wymagane posiadanie numeru telefonu ani konta w mediach społecznościowych.
- Użytkownik może bezpiecznie zalogować się bez konieczności podawania (lub pamiętania) hasła, co może być uciążliwe na urządzeniu mobilnym.
- Istniejącego użytkownika, który wcześniej logował się przy użyciu identyfikatora e-mail (hasła lub federacyjnego), można uaktualnić, aby logował się tylko przy użyciu adresu e-mail. Na przykład użytkownik, który zapomniał hasła, nadal może się zalogować bez konieczności resetowania hasła.
Zanim zaczniesz
Skonfiguruj swój projekt na Androida
Jeśli jeszcze tego nie zrobiłeś, dodaj Firebase do swojego projektu na Androida .
W pliku Gradle modułu (na poziomie aplikacji) (zwykle
<project>/<app-module>/build.gradle
) dodaj zależność dla biblioteki Firebase Authentication Android. Zalecamy używanie Firebase Android BoM do kontrolowania wersji bibliotek.Ponadto w ramach konfigurowania uwierzytelniania Firebase musisz dodać do swojej aplikacji pakiet SDK usług Google Play.
Kotlin+KTX
dependencies { // Import the BoM for the Firebase platform implementation platform('com.google.firebase:firebase-bom:32.1.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-ktx'
// Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.5.0' }Korzystając z Firebase Android BoM , Twoja aplikacja będzie zawsze korzystać ze zgodnych wersji bibliotek Firebase Android.
(Alternatywnie) Dodaj zależności biblioteki Firebase bez korzystania z BoM
Jeśli zdecydujesz się nie używać BoM Firebase, musisz określić każdą wersję biblioteki Firebase w jej wierszu zależności.
Pamiętaj, że jeśli używasz w swojej aplikacji wielu bibliotek Firebase, zdecydowanie zalecamy korzystanie z 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-ktx:22.0.0'
// Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.5.0' }Java
dependencies { // Import the BoM for the Firebase platform implementation platform('com.google.firebase:firebase-bom:32.1.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:20.5.0' }Korzystając z Firebase Android BoM , Twoja aplikacja będzie zawsze korzystać ze zgodnych wersji bibliotek Firebase Android.
(Alternatywnie) Dodaj zależności biblioteki Firebase bez korzystania z BoM
Jeśli zdecydujesz się nie używać BoM Firebase, musisz określić każdą wersję biblioteki Firebase w jej wierszu zależności.
Pamiętaj, że jeśli używasz w swojej aplikacji wielu bibliotek Firebase, zdecydowanie zalecamy korzystanie z 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:22.0.0'
// Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.5.0' }
Włącz logowanie za pomocą łącza e-mail w swoim projekcie Firebase
Aby logować użytkowników za pomocą łącza e-mail, musisz najpierw włączyć metodę logowania Dostawca poczty e-mail i Łącze e-mail w swoim projekcie Firebase:
- W konsoli Firebase otwórz sekcję Auth .
- Na karcie Metoda logowania włącz dostawcę adresu e-mail/hasła . Pamiętaj, że logowanie za pomocą adresu e-mail/hasła musi być włączone, aby można było korzystać z logowania za pomocą łącza e-mail.
- W tej samej sekcji włącz metodę logowania przez łącze e-mail (logowanie bez hasła) .
- Kliknij Zapisz .
Wyślij link uwierzytelniający na adres e-mail użytkownika
Aby zainicjować proces uwierzytelniania, przedstaw użytkownikowi interfejs z prośbą o podanie adresu e-mail, a następnie wywołaj funkcję sendSignInLinkToEmail
, aby poprosić Firebase o przesłanie linku uwierzytelniającego na adres e-mail użytkownika.
Skonstruuj obiekt ActionCodeSettings , który udostępnia Firebase instrukcje dotyczące tworzenia łącza e-mail. Ustaw następujące pola:
-
url
: precyzyjny link do osadzenia i wszelkie dodatkowe informacje, które mają zostać przekazane. Domena linku musi znajdować się na białej liście autoryzowanych domen w Konsoli Firebase, którą można znaleźć przechodząc do zakładki Metoda logowania (Uwierzytelnianie -> Metoda logowania). Link przekieruje użytkownika do tego adresu URL, jeśli aplikacja nie jest zainstalowana na jego urządzeniu i nie można jej zainstalować. -
androidPackageName
iIOSBundleId
: aplikacje używane po otwarciu łącza logowania na urządzeniu z systemem Android lub Apple. Dowiedz się więcej o konfigurowaniu linków dynamicznych Firebase do otwierania linków działań w wiadomościach e-mail za pośrednictwem aplikacji mobilnych. -
handleCodeInApp
: Ustaw na true. Operacja logowania musi być zawsze zakończona w aplikacji, w przeciwieństwie do innych działań e-mail poza pasmem (resetowanie hasła i weryfikacja adresu e-mail). Wynika to z faktu, że na końcu przepływu oczekuje się, że użytkownik będzie zalogowany, a jego stan uwierzytelnienia zostanie utrwalony w aplikacji. -
dynamicLinkDomain
: jeśli dla projektu zdefiniowano wiele niestandardowych domen linków dynamicznych, określ, która z nich ma być używana, gdy link ma zostać otwarty za pośrednictwem określonej aplikacji mobilnej (na przykładexample.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();
Aby dowiedzieć się więcej o ActionCodeSettings, zapoznaj się z sekcją Passing State in Email Actions .
-
Poproś użytkownika o jego adres e-mail.
Wyślij link uwierzytelniający na adres e-mail użytkownika i zapisz adres e-mail użytkownika na wypadek, gdyby użytkownik ukończył logowanie się za pomocą poczty e-mail 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."); } } });
Dokończ logowanie za pomocą linku e-mail
Względy bezpieczeństwa
Aby uniemożliwić użycie łącza logowania do zalogowania się jako niezamierzony użytkownik lub na niezamierzonym urządzeniu, Firebase Auth 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 wysłano łącze logowania.
Możesz usprawnić ten przepływ dla użytkowników, którzy otwierają łącze logowania na tym samym urządzeniu, na którym żądają łącza, przechowując ich adresy e-mail lokalnie — na przykład za pomocą SharedPreferences — podczas wysyłania wiadomości e-mail logowania. Następnie użyj tego adresu, aby zakończyć przepływ. 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 wszelkie poprzednie niezweryfikowane mechanizmy logowania zostaną usunięte z użytkownika, a wszystkie istniejące sesje zostaną unieważnione. Na przykład, jeśli 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ć osobie podszywającej się pod właściciela, która utworzyła to niezweryfikowane konto, ponowne zalogowanie się przy użyciu niezweryfikowanego adresu e-mail i hasła.
Upewnij się również, że używasz adresu URL HTTPS w produkcji, aby uniknąć potencjalnego przechwycenia linku przez serwery pośredniczące.
Kończenie logowania w aplikacji na Androida
Uwierzytelnianie Firebase używa linków dynamicznych Firebase do wysyłania łącza e-mail na urządzenie mobilne. Aby ukończyć logowanie za pomocą aplikacji mobilnej, aplikacja musi być skonfigurowana tak, aby wykrywała przychodzące łącze do aplikacji, analizowała powiązane głębokie łącze, a następnie dopełniała logowania.
Konfigurowanie linków dynamicznych Firebase
Firebase Auth używa łączy dynamicznych Firebase podczas wysyłania linku, który ma zostać otwarty w aplikacji mobilnej. Aby korzystać z tej funkcji, linki dynamiczne muszą być skonfigurowane w konsoli Firebase.
Włącz linki dynamiczne Firebase:
- W konsoli Firebase otwórz sekcję Linki dynamiczne .
Jeśli jeszcze nie zaakceptowałeś warunków korzystania z łączy dynamicznych i nie utworzyłeś domeny z łączami dynamicznymi, zrób to teraz.
Jeśli masz już utworzoną domenę z linkami dynamicznymi, zanotuj to. Domena z linkami dynamicznymi zazwyczaj wygląda tak, jak w poniższym przykładzie:
example.page.link
Ta wartość będzie potrzebna podczas konfigurowania aplikacji Apple lub Android do przechwytywania łącza przychodzącego.
Konfigurowanie aplikacji na Androida:
- Aby obsłużyć te linki z aplikacji na Androida, w ustawieniach projektu Firebase Console należy określić nazwę pakietu Android. Ponadto należy podać SHA-1 i SHA-256 certyfikatu aplikacji.
- Teraz, gdy dodałeś domenę łącza dynamicznego i upewniłeś się, że Twoja aplikacja na Androida jest poprawnie skonfigurowana, łącze dynamiczne przekieruje do Twojej aplikacji, zaczynając od działania programu uruchamiającego.
- Jeśli chcesz, aby link dynamiczny przekierowywał do określonej aktywności, musisz skonfigurować filtr intencji w pliku AndroidManifest.xml . Można to zrobić, określając domenę z łączem dynamicznym lub procedurę obsługi wiadomości e-mail w filtrze intencji. Domyślnie moduł obsługi akcji e-mail jest hostowany w domenie, jak w poniższym przykładzie:
PROJECT_ID.firebaseapp.com/
- Zastrzeżenia:
- Nie podawaj adresu URL ustawionego w ActionCodeSettings w filtrze intencji.
- Podczas tworzenia domeny z łączem dynamicznym mogłeś również utworzyć krótki link URL. Ten krótki adres URL nie zostanie przekazany; nie konfiguruj filtra intencji, aby przechwytywał go za pomocą atrybutu
android:pathPrefix
. Oznacza to, że nie będziesz w stanie złapać różnych linków dynamicznych w różnych częściach aplikacji. Możesz jednak sprawdzić parametr zapytaniamode
w łączu, aby zobaczyć, jaka operacja ma zostać wykonana, lub użyć metod zestawu SDK, takich jakisSignInWithEmailLink
, aby sprawdzić, czy łącze otrzymane przez aplikację działa zgodnie z oczekiwaniami.
- Aby uzyskać więcej informacji na temat otrzymywania linków dynamicznych, zapoznaj się z instrukcjami odbierania linków dynamicznych systemu Android .
Zweryfikuj łącze i zaloguj się
Po otrzymaniu łącza zgodnie z powyższym opisem sprawdź, czy jest ono przeznaczone do uwierzytelniania łącza w wiadomości e-mail i dokończ logowanie.
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 tym, jak obsługiwać logowanie za pomocą łącza e-mail w aplikacji Apple, zapoznaj się z przewodnikiem po platformach Apple .
Aby dowiedzieć się, jak obsługiwać logowanie za pomocą łącza e-mail w aplikacji internetowej, zapoznaj się z przewodnikiem internetowym .
Łączenie/ponowne uwierzytelnianie za pomocą łącza e-mail
Możesz także powiązać tę metodę uwierzytelniania z istniejącym użytkownikiem. Na przykład użytkownik uwierzytelniony wcześniej u innego dostawcy, na przykład numer telefonu, może dodać tę metodę logowania do swojego istniejącego konta.
Różnica byłaby 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()); } } });
Można tego również użyć do ponownego uwierzytelnienia użytkownika łącza 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ż jednak przepływ może zakończyć się na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany, przepływ ten może nie zostać ukończony. W takim przypadku użytkownikowi może zostać wyświetlony komunikat o błędzie, aby zmusić go do otwarcia łącza na tym samym urządzeniu. W łączu można przekazać pewien stan w celu dostarczenia informacji o typie operacji i identyfikatorze użytkownika.
Odróżnianie adresu e-mail/hasła od łącza e-mail
Jeśli obsługujesz zarówno logowanie oparte na haśle, jak i na podstawie linku za pomocą poczty e-mail, aby rozróżnić metodę logowania dla użytkownika hasła/linku, użyj fetchSignInMethodsForEmail
. Jest to przydatne w przypadku przepływów opartych na identyfikatorze, w których użytkownik jest najpierw proszony o podanie adresu e-mail, a następnie przedstawia metodę logowania:
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) }
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()); } } });
Jak opisano powyżej, adres e-mail/hasło i adres e-mail/link są uważane za tego samego EmailAuthProvider
(ten sam PROVIDER_ID
) z różnymi metodami logowania.
Następne kroki
Gdy użytkownik zaloguje się po raz pierwszy, tworzone jest nowe konto użytkownika, które jest łączone z poświadczeniami — czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy autoryzacji — za pomocą których użytkownik się logował. To nowe konto jest przechowywane jako część Twojego projektu Firebase i może służyć do identyfikacji użytkownika w każdej aplikacji w Twoim projekcie, niezależnie od tego, jak użytkownik się loguje.
W swoich aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z obiektu
FirebaseUser
. Zobacz Zarządzanie użytkownikami .W regułach bezpieczeństwa Firebase Realtime Database i Cloud Storage możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej
auth
i użyć go do kontrolowania, do jakich danych użytkownik ma dostęp.
Możesz zezwolić użytkownikom na logowanie się do Twojej aplikacji przy użyciu wielu dostawców uwierzytelniania, łącząc poświadczenia dostawcy uwierzytelniania z istniejącym kontem użytkownika.
Aby wylogować użytkownika, wywołaj signOut
:
Kotlin+KTX
Firebase.auth.signOut()
Java
FirebaseAuth.getInstance().signOut();