Użyj usługi Uwierzytelnianie Firebase, aby zalogować użytkownika. Wyślij mu e-maila z linkiem, który umożliwi mu zalogowanie się. W ramach tego procesu weryfikowany jest też adres e-mail użytkownika.
Logowanie się za pomocą adresu e-mail ma wiele zalet:
- Rejestracja i logowanie bez zbędnych formalności.
- mniejsze ryzyko ponownego użycia hasła w różnych aplikacjach, co może obniżyć bezpieczeństwo nawet dobrze dobranych haseł;
- Umożliwia uwierzytelnianie użytkownika i weryfikowanie, czy jest on prawowitym właścicielem adresu e-mail.
- Aby się zalogować, użytkownik potrzebuje tylko dostępu do konta e-mail. Nie musisz być właścicielem numeru telefonu ani konta w mediach społecznościowych.
- Użytkownik może logować się bezpiecznie bez konieczności podawania (lub zapamiętywania) hasła, co może być uciążliwe na urządzeniu mobilnym.
- Istniejący użytkownik, który wcześniej logował się przy użyciu identyfikatora e-mail (hasła lub federacji), może uzyskać możliwość logowania się tylko za pomocą adresu e-mail. Na przykład użytkownik, który zapomniał hasło, może się zalogować bez konieczności jego resetowania.
Zanim zaczniesz
Konfigurowanie projektu na Androida
Jeśli jeszcze tego nie zrobiono, dodaj Firebase do projektu na Androida.
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 wersji biblioteki.W ramach konfigurowania 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:33.7.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.3.0") }Gdy korzystasz z Firebase Android BoM, aplikacja zawsze używa zgodnych wersji bibliotek Firebase na Androida.
(Alternatywnie) Dodaj zależności biblioteki Firebase bez używania pakietu BoM
Jeśli zdecydujesz się nie używać Firebase BoM, musisz podać każdą wersję biblioteki Firebase w jej wierszu zależności.
Jeśli w aplikacji używasz kilku bibliotek Firebase, zdecydowanie zalecamy korzystanie z BoM do zarządzania wersjami bibliotek. Dzięki temu wszystkie wersje będą ze sobą 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.1.0")
// Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0") }
Włączanie logowania za pomocą usługi Email Link w projekcie Firebase
Aby umożliwić użytkownikom logowanie się za pomocą linku e-mail, musisz najpierw włączyć w projekcie Firebase dostawcę e-maili i metodę logowania za pomocą linku e-mail:
- W konsoli Firebase otwórz sekcję Autoryzacja.
- Na karcie Metoda logowania włącz dostawcę 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.
- W tej samej sekcji włącz metodę logowania Link w e-mailu (logowanie bez hasła).
- Kliknij Zapisz.
Wysyłanie linku uwierzytelniania na adres e-mail użytkownika
Aby zainicjować proces uwierzytelniania, wyświetl użytkownikowi interfejs, który poprosi go o podanie adresu e-mail, a następnie wywołaj funkcję sendSignInLinkToEmail
, aby poprosić Firebase o wysłanie linku uwierzytelniania na adres e-mail użytkownika.
Utwórz obiekt ActionCodeSettings, który zawiera instrukcje dla Firebase dotyczące tworzenia linku e-mail. Ustaw wartości w tych polach:
url
: precyzyjny link do osadzenia i dodatkowe stany, które mają być przekazywane. Domena linku musi znajdować się na liście autoryzowanych domen w konsoli Firebase (karta Metoda logowania -> Metoda logowania). Jeśli aplikacja nie jest zainstalowana na urządzeniu użytkownika i nie udało się jej zainstalować, link przekieruje użytkownika na ten adres URL.androidPackageName
iIOSBundleId
: aplikacje, których należy używać po otwarciu linku do logowania na urządzeniu z Androidem lub Apple. Dowiedz się więcej o konfigurowaniu linków dynamicznych Firebase, aby otwierać linki akcji e-maila w aplikacjach mobilnych.handleCodeInApp
: ustaw na wartość true. W przeciwieństwie do innych działań wykonywanych poza aplikacją (takich jak resetowanie hasła czy weryfikacja adresu e-mail) operacja logowania musi być zawsze wykonywana w aplikacji. Dzieje się tak, ponieważ na końcu procesu użytkownik powinien być zalogowany, a stan autoryzacji powinien być zachowany w aplikacji.dynamicLinkDomain
: jeśli w projekcie zdefiniowano wiele niestandardowych domen linków dynamicznych, określ, której z nich chcesz używać, gdy link ma być otwierany w określonej aplikacji mobilnej (np.example.page.link
). W przeciwnym razie pierwsza domena zostanie wybrana automatycznie.
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 ustawieniu ActionCodeSettings znajdziesz w sekcji Przekazywanie stanu w działaniach e-mail.
Poproś użytkownika o adres e-mail.
Wyślij link uwierzytelniania na adres e-mail użytkownika i zapisz ten adres na wypadek, gdyby użytkownik zalogował się przez e-maila 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."); } } });
Zaloguj się, klikając link w e-mailu
Potencjalne problemy z bezpieczeństwem
Aby zapobiec używaniu linku logowania przez nieuprawnionego użytkownika lub na nieuprawnionym urządzeniu, usługa Firebase Auth wymaga podania adresu e-mail użytkownika podczas procesu logowania. Aby zalogować się na konto, musisz podać adres e-mail, na który został wysłany link do logowania.
Możesz uprościć ten proces w przypadku użytkowników, którzy otwierają link logowania na tym samym urządzeniu, na którym wysłali prośbę o link, przechowując ich adresy e-mail lokalnie (np. za pomocą SharedPreferences) podczas wysyłania e-maila z linkiem. Następnie użyj tego adresu, aby dokończyć proces. Nie przekazuj adresu e-mail użytkownika w parametrach adresu URL przekierowania ani nie używaj go ponownie, ponieważ może to umożliwić wstrzyknięcie sesji.
Po zakończeniu logowania wszystkie wcześniejsze niesprawdzone mechanizmy logowania zostaną usunięte z konta użytkownika, a istniejące sesje zostaną unieważnione. Jeśli na przykład ktoś wcześniej utworzył niezweryfikowane konto z tym samym adresem e-mail i tym samym hasłem, hasło użytkownika zostanie usunięte, aby uniemożliwić osobie podszywającej się pod właściciela konta, która utworzyła to niezweryfikowane konto, ponowne zalogowanie się za pomocą tego niezweryfikowanego adresu e-mail i hasła.
Pamiętaj też, aby w produkcji używać adresu URL HTTPS, aby uniknąć przechwycenia linku przez serwery pośredniczące.
Logowanie się w aplikacji na Androida
Usługa Uwierzytelnianie Firebase korzysta z Linków dynamicznych Firebase, aby wysyłać linki e-maili na urządzenie mobilne. Aby umożliwić logowanie się za pomocą aplikacji mobilnej, musisz skonfigurować aplikację tak, aby wykrywała przychodzące linki aplikacji, analizowała precyzyjne linki i dokonywała logowania.
Konfigurowanie Linków dynamicznych Firebase
Firebase Auth używa linków dynamicznych Firebase podczas wysyłania linku, który ma być otwierany w aplikacji mobilnej. Aby korzystać z tej funkcji, musisz skonfigurować Linki dynamiczne w konsoli Firebase.
Włączanie Linków dynamicznych Firebase:
- W konsoli Firebase otwórz sekcję Dynamic Links.
-
Jeśli nie zaakceptowałeś(-aś) jeszcze warunków Dynamic Links i nie utworzyłeś(-aś) domeny Dynamic Links, zrób to teraz.
Jeśli domena Dynamic Links została już utworzona, zanotuj ją. Domena Dynamic Linkszazwyczaj wygląda tak:
example.page.link
Będzie ona potrzebna do skonfigurowania aplikacji na Apple lub Androida w celu przechwytywania przychodzącego linku.
Konfigurowanie aplikacji na Androida:
- Aby obsługiwać te linki w aplikacji na Androida, musisz podać nazwę pakietu Androida w ustawieniach projektu w Konsoli Firebase. Dodatkowo musisz podać hasz SHA-1 i SHA-256 certyfikatu aplikacji.
- Po dodaniu domeny linku dynamicznego i upewnieniu się, że aplikacja na Androida jest prawidłowo skonfigurowana, link dynamiczny przekieruje do Twojej aplikacji, zaczynając od aktywności w menu.
- Jeśli chcesz, aby link dynamiczny przekierowywał do określonej czynności, musisz skonfigurować filtr intencji w pliku AndroidManifest.xml. Możesz to zrobić, podając domenę linku dynamicznego lub przetwarzacz działania e-mail w filtrze intencji. Domyślnie moduł obsługi działania e-maila jest hostowany w domenie, takiej jak w tym przykładzie:
PROJECT_ID.firebaseapp.com/
- Zastrzeżenia:
- Nie podawaj w filtrze intencji adresu URL ustawionego w ustawieniach actionCode.
- Podczas tworzenia domeny linków dynamicznych możesz też utworzyć link do skróconego adresu URL. Ten krótki adres URL nie zostanie przekazany. Nie konfiguruj filtra intencji, aby wychwytywał go za pomocą atrybutu
android:pathPrefix
. Oznacza to, że nie będziesz w stanie wychwycić różnych linków dynamicznych w różnych częściach aplikacji. Możesz jednak sprawdzić parametr zapytaniamode
w linku, aby dowiedzieć się, jakiej operacji ma zostać wykonana, lub użyć metod pakietu SDK, takich jakisSignInWithEmailLink
, aby sprawdzić, czy link, który otrzymała Twoja aplikacja, działa zgodnie z Twoimi oczekiwaniami.
- Więcej informacji o otrzymywaniu linków dynamicznych znajdziesz w instrukcjach odbierania linków dynamicznych na Androida.
Weryfikowanie linku i logowanie
Gdy otrzymasz link w sposób opisany powyżej, sprawdź, czy jest on przeznaczony do uwierzytelniania za pomocą linku e-mail, 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 logowaniu się za pomocą linku e-mail w aplikacji Apple znajdziesz w przewodniku po platformach Apple.
Aby dowiedzieć się, jak obsługiwać logowanie za pomocą linku e-maila w aplikacji internetowej, zapoznaj się z przewodnikiem po aplikacjach internetowych.
Łączenie/ponowne uwierzytelnianie za pomocą linku e-maila
Możesz też połączyć tę metodę uwierzytelniania z dotychczasowym 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 dotychczasowego konta.
Różnica polega na tym, że druga połowa 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, który używa linku e-mail, przed wykonaniem operacji wrażliwej.
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()); } } });
Ponieważ jednak proces może zakończyć się na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany, może on nie zostać ukończony. W takim przypadku użytkownik może zobaczyć komunikat o błędzie, który zmusza 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 (UID).
Odradzane: rozróżnianie adresu e-mail i hasła od linku e-mail
Jeśli projekt został utworzony 15 września 2023 r. lub później, ochrona przed enumeracją 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óra była wcześniej zalecana do implementacji procesów z identyfikatorem na pierwszym miejscu.
Możesz wyłączyć ochronę przed wyliczaniem adresów e-mail w przypadku swojego projektu, ale nie zalecamy tego.
Aby dowiedzieć się więcej, zapoznaj się z dokumentacją dotyczącą ochrony przed wyliczaniem adresów e-mail.
Dalsze kroki
Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z danymi logowania, czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami dostawcy uwierzytelniania, za pomocą których użytkownik się zalogował. To nowe konto jest przechowywane w projekcie Firebase i może służyć do identyfikowania użytkownika we wszystkich aplikacjach w projekcie, niezależnie od tego, jak użytkownik się loguje.
-
W swoich aplikacjach możesz pobrać podstawowe informacje o profilu użytkownika z obiektu
FirebaseUser
. Zobacz sekcję Zarządzanie użytkownikami. W regułach Firebase Realtime Database i Cloud Storage Regułach bezpieczeństwa możesz pobrać z zmiennej
auth
unikalny identyfikator zalogowanego użytkownika i używać go do kontrolowania dostępu użytkownika do danych.
Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą danych uwierzytelniających od różnych dostawców, łącząc je z dotychczasowym kontem użytkownika.
Aby wylogować użytkownika, wywołaj funkcję
signOut
:
Kotlin
Firebase.auth.signOut()
Java
FirebaseAuth.getInstance().signOut();