Możesz użyć uwierzytelniania Firebase, aby zalogować użytkownika, wysyłając mu e-maila z linkiem, który może kliknąć, aby się zalogować. Podczas procesu weryfikacji zweryfikowany jest też adres e-mail użytkownika.
Logowanie się przez e-maila ma wiele zalet:
- Rejestracja i logowanie przebiegają sprawnie.
- Mniejsze ryzyko ponownego użycia tego samego hasła w różnych aplikacjach, co może zagrażać bezpieczeństwu nawet dobrze dobranych haseł.
- Możliwość uwierzytelnienia użytkownika, a jednocześnie potwierdzanie, że jest on prawowitym właścicielem adresu e-mail.
- Aby się zalogować, użytkownik potrzebuje tylko dostępnego konta e-mail. Nie jest wymagane posiadanie 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ące konto użytkownika, które wcześniej logowało się przy użyciu identyfikatora e-mail (hasła lub konta sfederowanego), można przejść na wyższą wersję, aby logować się przy użyciu samego adresu e-mail. Na przykład użytkownik, który nie pamięta hasła, może się zalogować bez konieczności resetowania hasła.
Zanim zaczniesz
Skopiuj fragment kodu inicjowania z konsoli Firebase do swojego projektu w sposób opisany w artykule Dodawanie Firebase do projektu JavaScript.
Włącz logowanie się w projekcie Firebase za pomocą linku e-mail
Aby logować użytkowników za pomocą linku w e-mailu, musisz najpierw włączyć w projekcie Firebase metodę logowania Dostawca poczty e-mail i metodę logowania się za pomocą linku w e-mailu:
- W konsoli Firebase otwórz sekcję Uwierzytelnianie.
- Na karcie Metoda logowania włącz dostawcę E-mail/hasła. Pamiętaj, że aby korzystać z logowania za pomocą linku e-mail, 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, pokaż użytkownikowi interfejs, który prosi o podanie adresu e-mail, a następnie wywołaj sendSignInLinkToEmail
z prośbą o wysłanie przez Firebase linku uwierzytelniającego na jego adres e-mail.
Utwórz obiekt
ActionCodeSettings
, który dostarcza Firebase z instrukcjami, jak utworzyć link do e-maila. Ustaw wartości w tych polach:url
: precyzyjny link do umieszczenia i wszystkie dodatkowe stany do przekazania. Domena linku należy dodać do listy autoryzowanych domen w konsoli Firebase. Aby ją znaleźć, przejdź na kartę Metoda logowania (Uwierzytelnianie -> Ustawienia).android
iios
: aplikacje używane po otwarciu linku logowania na urządzeniu z Androidem lub urządzeniu firmy Apple. Dowiedz się więcej o tym, jak skonfigurować Linki dynamiczne Firebase, aby otwierać linki do działań w e-mailach w aplikacjach mobilnych.handleCodeInApp
: ustaw wartość prawda. Operacja logowania musi być zawsze wykonywana w aplikacji, w przeciwieństwie do innych pozapasmowych działań związanych z e-mailami (resetowania hasła i potwierdzania adresu e-mail). Wynika to z faktu, że pod koniec procesu użytkownik musi być zalogowany, a jego stan uwierzytelniania musi pozostać w aplikacji.dynamicLinkDomain
: jeśli w projekcie zdefiniowano wiele niestandardowych domen linków dynamicznych, określ, która ma być używana, gdy link ma być otwierany przez określoną aplikację mobilną (np.example.page.link
). W przeciwnym razie automatycznie zostanie wybrana pierwsza domena.Web
const actionCodeSettings = { // URL you want to redirect back to. The domain (www.example.com) for this // URL must be in the authorized domains list in the Firebase Console. url: 'https://www.example.com/finishSignUp?cartId=1234', // This must be true. handleCodeInApp: true, iOS: { bundleId: 'com.example.ios' }, android: { packageName: 'com.example.android', installApp: true, minimumVersion: '12' }, dynamicLinkDomain: 'example.page.link' };
Web
var actionCodeSettings = { // URL you want to redirect back to. The domain (www.example.com) for this // URL must be in the authorized domains list in the Firebase Console. url: 'https://www.example.com/finishSignUp?cartId=1234', // This must be true. handleCodeInApp: true, iOS: { bundleId: 'com.example.ios' }, android: { packageName: 'com.example.android', installApp: true, minimumVersion: '12' }, dynamicLinkDomain: 'example.page.link' };
Więcej informacji o ActionCodeSettings znajdziesz w sekcji Stan przekazywania w czynnościach poczty e-mail.
Poproś użytkownika o podanie adresu e-mail.
Wyślij link uwierzytelniania na adres e-mail użytkownika i zapisz adres e-mail użytkownika, na wypadek gdyby użytkownik logował się za pomocą adresu e-mail na tym samym urządzeniu.
Web
import { getAuth, sendSignInLinkToEmail } from "firebase/auth"; const auth = getAuth(); sendSignInLinkToEmail(auth, email, actionCodeSettings) .then(() => { // The link was successfully sent. Inform the user. // Save the email locally so you don't need to ask the user for it again // if they open the link on the same device. window.localStorage.setItem('emailForSignIn', email); // ... }) .catch((error) => { const errorCode = error.code; const errorMessage = error.message; // ... });
Web
firebase.auth().sendSignInLinkToEmail(email, actionCodeSettings) .then(() => { // The link was successfully sent. Inform the user. // Save the email locally so you don't need to ask the user for it again // if they open the link on the same device. window.localStorage.setItem('emailForSignIn', email); // ... }) .catch((error) => { var errorCode = error.code; var errorMessage = error.message; // ... });
Dokończ logowanie się za pomocą linku z e-maila
Potencjalne problemy z bezpieczeństwem
Aby zapobiec użyciu linku logowania do zalogowania się jako niezamierzony użytkownik lub na niewłaściwym urządzeniu, Uwierzytelnianie Firebase wymaga podania adresu e-mail użytkownika podczas logowania się. Aby logowanie się powiodło, ten adres e-mail musi być zgodny z adresem, na który pierwotnie przesłano link.
Możesz usprawnić ten proces w przypadku użytkowników, którzy otworzą link logowania na tym samym urządzeniu, na tym samym urządzeniu, zapisując swój adres e-mail lokalnie – na przykład przy użyciu localStorage lub plików cookie – w momencie wysyłania e-maila umożliwiającego zalogowanie się. Następnie użyj tego adresu do dokończenia procesu. Nie przekazuj adresu e-mail użytkownika w parametrach przekierowania ani nie używaj go ponownie, ponieważ może to umożliwić wstrzykiwanie sesji.
Po zakończeniu logowania wszystkie wcześniejsze niezweryfikowane mechanizmy logowania zostaną usunięte z konta użytkownika, a wszystkie istniejące 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ć osobie podszywającej się pod inną osobę, która zgłosiła prawo własności i utworzyła niezweryfikowane konto, ponownie zalogowanie się przy użyciu niezweryfikowanego adresu e-mail i hasła.
Upewnij się też, że w środowisku produkcyjnym używasz adresu URL HTTPS, aby zapobiec potencjalnemu przechwyceniu linku przez serwery pośrednie.
Logowanie się na stronie internetowej
Format precyzyjnego linku w e-mailu jest taki sam jak format używany w przypadku pozapasmowych działań e-mail (weryfikacja adresu e-mail, resetowanie hasła i unieważnianie zmiany adresu e-mail).
Uwierzytelnianie Firebase upraszcza tę weryfikację, udostępniając interfejs isSignInWithEmailLink
API, który pozwala sprawdzić, czy link prowadzi do logowania za pomocą linku e-mail.
Aby dokończyć logowanie na stronie docelowej, wywołaj signInWithEmailLink
, podając adres e-mail użytkownika i rzeczywisty link e-mail zawierający kod jednorazowy.
Web
import { getAuth, isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth"; // Confirm the link is a sign-in with email link. const auth = getAuth(); if (isSignInWithEmailLink(auth, window.location.href)) { // Additional state parameters can also be passed via URL. // This can be used to continue the user's intended action before triggering // the sign-in operation. // Get the email if available. This should be available if the user completes // the flow on the same device where they started it. let email = window.localStorage.getItem('emailForSignIn'); if (!email) { // User opened the link on a different device. To prevent session fixation // attacks, ask the user to provide the associated email again. For example: email = window.prompt('Please provide your email for confirmation'); } // The client SDK will parse the code from the link for you. signInWithEmailLink(auth, email, window.location.href) .then((result) => { // Clear email from storage. window.localStorage.removeItem('emailForSignIn'); // You can access the new user by importing getAdditionalUserInfo // and calling it with result: // getAdditionalUserInfo(result) // You can access the user's profile via: // getAdditionalUserInfo(result)?.profile // You can check if the user is new or existing: // getAdditionalUserInfo(result)?.isNewUser }) .catch((error) => { // Some error occurred, you can inspect the code: error.code // Common errors could be invalid email and invalid or expired OTPs. }); }
Web
// Confirm the link is a sign-in with email link. if (firebase.auth().isSignInWithEmailLink(window.location.href)) { // Additional state parameters can also be passed via URL. // This can be used to continue the user's intended action before triggering // the sign-in operation. // Get the email if available. This should be available if the user completes // the flow on the same device where they started it. var email = window.localStorage.getItem('emailForSignIn'); if (!email) { // User opened the link on a different device. To prevent session fixation // attacks, ask the user to provide the associated email again. For example: email = window.prompt('Please provide your email for confirmation'); } // The client SDK will parse the code from the link for you. firebase.auth().signInWithEmailLink(email, window.location.href) .then((result) => { // Clear email from storage. window.localStorage.removeItem('emailForSignIn'); // You can access the new user via result.user // Additional user info profile not available via: // result.additionalUserInfo.profile == null // You can check if the user is new or existing: // result.additionalUserInfo.isNewUser }) .catch((error) => { // Some error occurred, you can inspect the code: error.code // Common errors could be invalid email and invalid or expired OTPs. }); }
Logowanie się w aplikacji mobilnej
Uwierzytelnianie Firebase używa Linków dynamicznych Firebase do wysyłania linku e-mail na urządzenie mobilne. Aby zakończyć logowanie za pomocą aplikacji mobilnej, należy skonfigurować aplikację tak, aby wykrywała przychodzący link do aplikacji, przeanalizowała precyzyjny link, a następnie logował się w taki sam sposób jak w przypadku interfejsu internetowego.
Więcej informacji o logowaniu się w aplikacji na Androida za pomocą linku e-mail znajdziesz w przewodniku po Androidzie.
Więcej informacji o tym, jak obsługiwać logowanie się za pomocą linku przez e-maila w aplikacji Apple, znajdziesz w przewodniku po platformach Apple.
Łączenie/ponowne uwierzytelnianie za pomocą linku w e-mailu
Możesz też powiązać tę metodę uwierzytelniania z istniejącym użytkownikiem. Na przykład użytkownik, który wcześniej uwierzytelnił się u innego dostawcy (np. przy użyciu numeru telefonu), może dodać tę metodę logowania do swojego istniejącego konta.
Różnica będzie widoczna w drugiej połowie operacji:
Web
import { getAuth, linkWithCredential, EmailAuthProvider } from "firebase/auth"; // Construct the email link credential from the current URL. const credential = EmailAuthProvider.credentialWithLink( email, window.location.href); // Link the credential to the current user. const auth = getAuth(); linkWithCredential(auth.currentUser, credential) .then((usercred) => { // The provider is now successfully linked. // The phone user can now sign in with their phone number or email. }) .catch((error) => { // Some error occurred. });
Web
// Construct the email link credential from the current URL. var credential = firebase.auth.EmailAuthProvider.credentialWithLink( email, window.location.href); // Link the credential to the current user. firebase.auth().currentUser.linkWithCredential(credential) .then((usercred) => { // The provider is now successfully linked. // The phone user can now sign in with their phone number or email. }) .catch((error) => { // Some error occurred. });
W ten sposób możesz też ponownie uwierzytelnić użytkownika powiązanego z linkiem e-mail przed uruchomieniem operacji poufnej.
Web
import { getAuth, reauthenticateWithCredential, EmailAuthProvider } from "firebase/auth"; // Construct the email link credential from the current URL. const credential = EmailAuthProvider.credentialWithLink( email, window.location.href); // Re-authenticate the user with this credential. const auth = getAuth(); reauthenticateWithCredential(auth.currentUser, credential) .then((usercred) => { // The user is now successfully re-authenticated and can execute sensitive // operations. }) .catch((error) => { // Some error occurred. });
Web
// Construct the email link credential from the current URL. var credential = firebase.auth.EmailAuthProvider.credentialWithLink( email, window.location.href); // Re-authenticate the user with this credential. firebase.auth().currentUser.reauthenticateWithCredential(credential) .then((usercred) => { // The user is now successfully re-authenticated and can execute sensitive // operations. }) .catch((error) => { // Some error occurred. });
Proces ten może jednak nie zostać ukończony na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany. W takim przypadku może wyświetlić się komunikat o błędzie, który będzie wymuszał na nim otwarcie linku na tym samym urządzeniu. W linku można przekazać informacje o typie działania i identyfikatorze UID użytkownika.
Wycofane: odróżnianie hasła i adresu e-mail od linku w e-mailu
Jeśli Twój projekt został utworzony 15 września 2023 r. lub później, ochrona przed wyliczeniem adresów e-mail jest domyślnie włączona. Ta funkcja zwiększa bezpieczeństwo kont użytkowników Twojego projektu, ale wyłącza metodę fetchSignInMethodsForEmail()
, którą wcześniej rekomendowaliśmy w celu implementacji przepływów skoncentrowanych na identyfikatorze.
Chociaż możesz wyłączyć ochronę wyliczania adresów e-mail w projekcie, nie zalecamy tego.
Więcej informacji znajdziesz w dokumentacji dotyczącej ochrony przed wyliczeniem adresów e-mail.
Domyślny szablon e-maila dotyczącego logowania za pomocą linku
Domyślny szablon e-maila zawiera sygnaturę czasową w temacie i treści e-maila, dzięki czemu kolejne e-maile nie są zwinięte w jeden wątek, a link jest ukryty.
Ten szablon dotyczy tych języków:
Kod | Język |
---|---|
ar | arabski |
zh-CN | chiński (uproszczony) |
zh-TW | chiński (tradycyjny) |
niderlandzki | niderlandzki |
en | angielski |
en-GB | angielski (Wielka Brytania) |
fr | Francuski |
de | niemiecki |
id | Indonezyjski |
jego | włoski |
ja | japoński |
ko | Koreański |
pl | Polski |
pt-BR | portugalski (Brazylia) |
pt-PT | portugalski (Portugalia) |
ru | Rosyjski |
es | Hiszpański |
ES-419 | hiszpański (Ameryka Łacińska) |
th | tajski |
Dalsze kroki
Gdy użytkownik loguje się po raz pierwszy, tworzone jest nowe konto użytkownika, które jest łączone z danymi logowania (nazwa użytkownika i hasło, numer telefonu lub informacje o dostawcy uwierzytelniania). Nowe konto jest przechowywane w ramach Twojego projektu Firebase i może być używane do identyfikowania użytkowników we wszystkich aplikacjach w Twoim projekcie niezależnie od tego, jak się on loguje.
-
Zalecanym sposobem na poznanie stanu uwierzytelniania użytkownika w aplikacjach jest ustawienie obserwatora w obiekcie
Auth
. Dzięki temu można uzyskać podstawowe informacje o profilu użytkownika z obiektuUser
. Zobacz Zarządzanie użytkownikami. W regułach zabezpieczeń Bazy danych czasu rzeczywistego Firebase i Cloud Storage możesz pobrać ze zmiennej
auth
unikalny identyfikator użytkownika zalogowanego użytkownika i użyć go do kontrolowania, do jakich danych użytkownik ma dostęp.
Możesz zezwolić użytkownikom na logowanie się w aplikacji przy użyciu różnych dostawców uwierzytelniania, łącząc dane logowania dostawcy uwierzytelniania z istniejącym kontem użytkownika.
Aby wylogować użytkownika, wywołaj
signOut
:
Web
import { getAuth, signOut } from "firebase/auth"; const auth = getAuth(); signOut(auth).then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });
Web
firebase.auth().signOut().then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });