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ć. W trakcie tego procesu weryfikowany jest też adres e-mail użytkownika.
Logowanie się za pomocą adresu e-mail ma wiele korzyści:
- Łatwa rejestracja i logowanie.
- Mniejsze ryzyko ponownego użycia hasła w różnych aplikacjach, co może osłabić bezpieczeństwo nawet dobrze dobranych haseł.
- Możliwość uwierzytelnienia użytkownika przy jednoczesnym sprawdzeniu, czy jest on prawowitym właścicielem adresu e-mail.
- Aby się zalogować, użytkownik potrzebuje tylko dostępnego konta e-mail. Nie musi mieć numeru telefonu ani konta w mediach społecznościowych.
- Użytkownik może bezpiecznie się zalogować bez konieczności podawania (ani 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 federacyjnego), może zostać uaktualniony, aby logować się tylko za pomocą adresu e-mail. Jeśli np. użytkownik zapomni hasła, nadal będzie mógł się zalogować bez konieczności jego resetowania.
Zanim zaczniesz
Jeśli jeszcze tego nie zrobisz, skopiuj fragment kodu inicjującego z Firebase konsoli do projektu zgodnie z opisem w Dodawanie Firebase do projektu JavaScript.
Włączanie logowania za pomocą linku w e-mailu 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:
W konsoli Firebase otwórz Zabezpieczenia > Uwierzytelnianie.
Na karcie Metoda logowania włącz metodę logowania Adres e-mail i 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 dostawcę logowania Link w e-mailu (logowanie bez hasła).
Kliknij Zapisz.
Wysyłanie linku uwierzytelniającego na adres e-mail użytkownika
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 uwierzytelniającego na adres e-mail użytkownika.
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 osadzenia i dodatkowy stan do przekazania. Jeśli jeszcze tego nie zrobisz, dodaj swoją domenę do listy autoryzowanych domen:W konsoli Firebase otwórz kartę Zabezpieczenia > Uwierzytelnianie > Ustawienia.
W sekcji Autoryzowane domeny kliknij Dodaj domenę i dodaj swoją domenę.
androidiios: pomagają usłudze Firebase Authentication określić, czy ma utworzyć link tylko do witryny, czy link mobilny, który zostanie otwarty na urządzeniu z Androidem lub Apple.handleCodeInApp: ustaw na true. W przeciwieństwie do innych działań wykonywanych poza pasmem (resetowanie hasła i weryfikacja adresu e-mail) operację logowania trzeba zawsze dokończyć w aplikacji. Dzieje się tak, ponieważ na końcu procesu użytkownik powinien być zalogowany, a jego stan uwierzytelnienia 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 zostać otwarty w określonej aplikacji mobilnej. W przeciwnym razie automatycznie zostanie wybrana domena domyślna (np. ).PROJECT_ID.firebaseapp.comdynamicLinkDomain: wycofany. Nie podawaj tego parametru.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' }, // The domain must be configured in Firebase Hosting and owned by the project. linkDomain: 'custom-domain.com' };
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
ActionCodeSettingsznajdziesz w sekcji Przekazywanie stanu w działaniach związanych z e-mailami.Poproś użytkownika o podanie adresu e-mail.
Wyślij link uwierzytelniający na adres e-mail użytkownika i zapisz ten adres na wypadek, gdyby użytkownik dokończył logowanie za pomocą e-maila 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ńczenie logowania za pomocą linku w e-mailu
Potencjalne problemy z bezpieczeństwem
Aby uniemożliwić użycie linku do logowania w celu zalogowania się jako niepożądany użytkownik lub na niepożądanym urządzeniu, usługa Uwierzytelnianie Firebase wymaga podania adresu e-mail użytkownika podczas dokonywania 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 żądają, zapisując ich adres e-mail lokalnie – np. za pomocą localStorage lub plików cookie – podczas wysyłania 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 istniejące sesje zostaną unieważnione. Jeśli np. 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ć oszustowi, który przejął własność i utworzył to niezweryfikowane konto, ponowne zalogowanie się za pomocą niezweryfikowanego adresu e-mail i hasła.
Upewnij się też, że w środowisku produkcyjnym używasz adresu URL HTTPS, aby uniknąć przechwycenia linku przez serwery pośredniczące.
Dokończenie logowania na stronie internetowej
Format precyzyjnego linku w e-mailu jest taki sam jak
format używany w przypadku działań związanych z e-mailami wykonywanych poza pasmem
(weryfikacja adresu e-mail, resetowanie hasła i cofnięcie zmiany adresu e-mail).
Usługa Uwierzytelnianie Firebase upraszcza to sprawdzanie, udostępniając interfejs API isSignInWithEmailLink, który pozwala sprawdzić, czy link jest linkiem do logowania za pomocą e-maila.
Aby dokończyć logowanie na stronie docelowej, wywołaj funkcję signInWithEmailLink, podając adres e-mail użytkownika i rzeczywisty link w e-mailu 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. }); }
Dokończenie logowania w aplikacji mobilnej
Firebase Authentication używa Firebase Hosting do wysyłania linku w e-mailu na urządzenie mobilne. Aby dokończyć logowanie za pomocą aplikacji mobilnej, aplikacja musi być skonfigurowana tak, aby wykrywała przychodzący link do aplikacji, analizowała precyzyjny link i dokonywała logowania tak jak w przypadku procesu internetowego.
Więcej informacji o tym, jak obsługiwać logowanie za pomocą linku w e-mailu w aplikacji na Androida , znajdziesz w przewodniku po Androidzie.
Więcej informacji o tym, jak obsługiwać logowanie za pomocą linku w e-mailu w aplikacji Apple , znajdziesz w przewodniku po platformach Apple.
Łączenie/ponowne uwierzytelnianie za pomocą linku w e-mailu
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 dotychczasowego 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. });
Możesz też użyć tej metody do ponownego uwierzytelnienia użytkownika linku w e-mailu przed wykonaniem operacji wymagającej zachowania poufności.
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. });
Jednak ponieważ proces może się zakończyć na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany, ten proces może się nie powieść. W takim przypadku użytkownikowi można wyświetlić błąd, aby wymusić otwarcie linku na tym samym urządzeniu. W linku można przekazać pewien stan, aby podać informacje o typie operacji i identyfikatorze UID użytkownika.
Wycofane: odróżnianie logowania za pomocą adresu e-mail i hasła od logowania za pomocą linku w e-mailu
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 w projekcie, ale wyłącza metodę fetchSignInMethodsForEmail(), której wcześniej zalecaliśmy używać do implementowania procesów opartych na identyfikatorze.
Możesz wyłączyć ochronę przed wyliczaniem adresów e-mail w projekcie, ale nie zalecamy tego robić.
Więcej informacji znajdziesz w dokumentacji dotyczącej ochrony przed wyliczaniem adresów e-mail.
Domyślny szablon e-maila do 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ą zwijane w jeden wątek, a link nie jest ukryty.
Ten szablon jest dostępny w tych językach:
| Kod | Język |
|---|---|
| ar | arabski |
| zh-CN | chiński (uproszczony) |
| zh-TW | chiński (tradycyjny) |
| nl | niderlandzki |
| en | angielski |
| en-GB | angielski (Wlk. Brytania) |
| fr | francuski |
| de | niemiecki |
| id | indonezyjski |
| it | 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 zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z danymi logowania – 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 projekcie w Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od sposobu logowania.
-
W aplikacjach zalecamy ustawienie obserwatora w obiekcie
Auth, aby poznać stan uwierzytelnienia użytkownika. Następnie możesz pobrać podstawowe informacje o profilu użytkownika z obiektuUser. Zobacz Zarządzanie użytkownikami. W regułach bezpieczeństwa Firebase Realtime Database i Cloud Storage bazy danych czasu rzeczywistego Firebase i Cloud Storage, możesz pobrać unikalny identyfikator użytkownika zalogowanego z zmiennej
auth, i użyć go do kontrolowania, do jakich danych użytkownik ma dostęp.
Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą wielu dostawców uwierzytelniania przez połączenie danych logowania dostawcy uwierzytelniania z istniejącym kontem użytkownika.
Aby wylogować użytkownika, wywołaj funkcję
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. });