Puoi utilizzare Firebase Authentication per consentire a un utente di accedere inviandogli un'email contenente un link su cui può fare clic per accedere. Durante la procedura, viene verificato anche l'indirizzo email dell'utente.
L'accesso tramite email offre numerosi vantaggi:
- Registrazione e accesso semplici.
- Riduzione del rischio di riutilizzo delle password nelle applicazioni, il che può compromettere la sicurezza anche di password ben selezionate.
- La possibilità di autenticare un utente e verificare che sia il proprietario legittimo di un indirizzo email.
- Per accedere, un utente ha bisogno solo di un account email accessibile. Non è richiesta la proprietà di un numero di telefono o di un account di social media.
- Un utente può accedere in modo sicuro senza dover fornire (o ricordare) una password, che può essere scomoda su un dispositivo mobile.
- Un utente esistente che ha eseguito l'accesso in precedenza con un identificatore email (password o federato) può essere aggiornato per accedere solo con l'email. Ad esempio, un utente che ha dimenticato la password può comunque accedere senza doverla reimpostare.
Prima di iniziare
Se non l'hai ancora fatto, copia lo snippet di inizializzazione dalla console Firebase al tuo progetto come descritto in Aggiungere Firebase al tuo progetto JavaScript.
Attivare l'accesso con link via email per il tuo progetto Firebase
Per consentire agli utenti di accedere tramite link email, devi prima attivare il provider email e il metodo di accesso tramite link email per il tuo progetto Firebase:
Nella console Firebase, vai a Sicurezza > Autenticazione.
Nella scheda Metodo di accesso, attiva il metodo di accesso Email/password. Tieni presente che l'accesso con email/password deve essere attivato per utilizzare l'accesso con link via email.
Nella stessa sezione, attiva il provider di accesso Link via email (accesso senza password).
Fai clic su Salva.
Invia un link di autenticazione all'indirizzo email dell'utente
Per avviare il flusso di autenticazione, mostra all'utente un'interfaccia che
gli chiede di fornire il suo indirizzo email e poi chiama
sendSignInLinkToEmail per richiedere a Firebase di inviare il link di autenticazione all'indirizzo email dell'utente.
Costruisci l'oggetto
ActionCodeSettings, che fornisce a Firebase le istruzioni su come costruire il link email. Imposta i seguenti campi:url: il link diretto da incorporare e qualsiasi stato aggiuntivo da trasmettere. Se non l'hai ancora fatto, aggiungi il tuo dominio all'elenco dei domini autorizzati:Nella console Firebase, vai alla scheda Sicurezza > Autenticazione > Impostazioni.
Nella sezione Domini autorizzati, fai clic su Aggiungi dominio e aggiungi il tuo dominio.
androideios: aiutano Firebase Authentication a determinare se deve creare un link solo web o un link mobile che viene aperto su un dispositivo Android o Apple.handleCodeInApp: impostato su true. L'operazione di accesso deve essere sempre completata nell'app, a differenza di altre azioni email fuori banda (reimpostazione password e verifiche email). Questo perché, alla fine del flusso, l'utente deve aver eseguito l'accesso e il suo stato di autenticazione deve essere mantenuto all'interno dell'app.linkDomain: quando per un progetto vengono definiti domini di link Hosting personalizzati, specifica quale utilizzare quando il link deve essere aperto da un'app mobile specificata. In caso contrario, il dominio predefinito viene selezionato automaticamente (ad esempio, ).PROJECT_ID.firebaseapp.comdynamicLinkDomain: deprecato. Non specificare questo parametro.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' };
Per scoprire di più su
ActionCodeSettings, consulta la sezione Trasferimento dello stato nelle azioni email.Chiedi all'utente il suo indirizzo email.
Invia il link di autenticazione all'email dell'utente e salva l'indirizzo email nel caso in cui l'utente completi l'accesso con l'email sullo stesso dispositivo.
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; // ... });
Completa l'accesso con il link nell'email
Problemi di sicurezza
Per impedire che un link di accesso venga utilizzato per accedere come utente non previsto o su un dispositivo non previsto, Firebase Auth richiede che l'indirizzo email dell'utente venga fornito al termine del flusso di accesso. Per l'accesso, questo indirizzo email deve corrispondere a quello a cui è stato inviato originariamente il link di accesso.
Puoi semplificare questo flusso per gli utenti che aprono il link di accesso sullo stesso dispositivo su cui lo richiedono memorizzando il loro indirizzo email localmente, ad esempio utilizzando localStorage o i cookie, quando invii l'email di accesso. Poi, utilizza questo indirizzo per completare il flusso. Non trasmettere l'email dell'utente nei parametri dell'URL di reindirizzamento e riutilizzarla perché ciò potrebbe consentire iniezioni di sessione.
Una volta completato l'accesso, qualsiasi meccanismo di accesso non verificato precedente verrà rimosso dall'utente e tutte le sessioni esistenti verranno invalidate. Ad esempio, se in precedenza qualcuno ha creato un account non verificato con lo stesso indirizzo email e la stessa password, la password dell'utente verrà rimossa per impedire all'impostore che ha rivendicato la proprietà e creato l'account non verificato di accedere di nuovo con l'indirizzo email e la password non verificati.
Inoltre, assicurati di utilizzare un URL HTTPS in produzione per evitare che il link venga potenzialmente intercettato da server intermediari.
Completare l'accesso in una pagina web
Il formato del link diretto del link email è lo stesso del
formato utilizzato per le azioni email fuori banda
(verifica email, reimpostazione password e revoca della modifica dell'email).
Firebase Auth semplifica questo controllo fornendo l'API isSignInWithEmailLink per verificare se un link è un accesso con link email.
Per completare l'accesso alla pagina di destinazione, chiama signInWithEmailLink con l'indirizzo email dell'utente e il link email effettivo contenente il codice monouso.
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. }); }
Completare l'accesso in un'app mobile
Firebase Authentication utilizza Firebase Hosting per inviare il link email a un dispositivo mobile. Per completare l'accesso tramite l'applicazione mobile, l'applicazione deve essere configurata per rilevare il link dell'applicazione in entrata, analizzare il link diretto sottostante e quindi completare l'accesso come avviene tramite il flusso web.
Per scoprire di più su come gestire l'accesso con link email in un'applicazione Android, consulta la guida per Android.
Per scoprire di più su come gestire l'accesso con il link email in un'applicazione Apple, consulta la guida alle piattaforme Apple.
Collegamento/riautenticazione con link email
Puoi anche collegare questo metodo di autenticazione a un utente esistente. Ad esempio, un utente che in precedenza si è autenticato con un altro provider, ad esempio un numero di telefono, può aggiungere questo metodo di accesso al proprio account esistente.
La differenza si trova nella seconda metà dell'operazione:
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. });
Può essere utilizzato anche per eseguire nuovamente l'autenticazione di un utente con link email prima di eseguire un'operazione sensibile.
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. });
Tuttavia, poiché il flusso potrebbe terminare su un dispositivo diverso in cui l'utente originale non ha eseguito l'accesso, questo flusso potrebbe non essere completato. In questo caso, all'utente può essere mostrato un errore per forzarlo ad aprire il link sullo stesso dispositivo. Alcuni stati possono essere passati nel link per fornire informazioni sul tipo di operazione e sull'UID utente.
Ritirato: differenziazione tra email e password e link email
Se hai creato il tuo progetto a partire dal 15 settembre 2023, la protezione dall'enumerazione delle email
è abilitata per impostazione predefinita. Questa funzionalità migliora la sicurezza degli account utente del tuo progetto, ma disattiva il metodo fetchSignInMethodsForEmail(), che in precedenza consigliavamo di implementare per i flussi di autenticazione con identificatore.
Anche se puoi disattivare la protezione dall'enumerazione email per il tuo progetto, ti sconsigliamo di farlo.
Per ulteriori dettagli, consulta la documentazione sulla protezione dall'enumerazione delle email.
Modello email predefinito per l'accesso tramite link
Il modello di email predefinito include un timestamp nell'oggetto e nel corpo dell'email in modo che le email successive non vengano compresse in un unico thread e il link non venga nascosto.
Questo modello si applica alle seguenti lingue:
| Codice | Lingua |
|---|---|
| ar | Arabo |
| zh-CN | Cinese (semplificato) |
| zh-TW | Cinese (tradizionale) |
| nl | Olandese |
| it | Inglese |
| en-GB | Inglese (UK) |
| fr | Francese |
| de | Tedesco |
| id | Indonesiano |
| che li ricevano. | Italiano |
| ja | Giapponese |
| ko | Coreano |
| pl | Polacco |
| pt-BR | Portoghese (Brasile) |
| pt-PT | Portoghese (Portogallo) |
| ru | Russo |
| es | Spagnolo |
| es-419 | Spagnolo (America Latina) |
| th | Thailandese |
Passaggi successivi
Dopo il primo accesso di un utente, viene creato un nuovo account utente e collegato alle credenziali, ovvero nome utente e password, numero di telefono o informazioni del fornitore di autenticazione, con cui l'utente ha eseguito l'accesso. Questo nuovo account viene memorizzato come parte del tuo progetto Firebase e può essere utilizzato per identificare un utente in ogni app del tuo progetto, indipendentemente dalla modalità di accesso.
-
Nelle tue app, il modo consigliato per conoscere lo stato di autenticazione dell'utente è impostare un observer sull'oggetto
Auth. Puoi quindi ottenere le informazioni di base del profilo dell'utente dall'oggettoUser. Vedi Gestire gli utenti. Nelle regole di sicurezza di Firebase Realtime Database e Cloud Storage, puoi ottenere l'ID utente univoco dell'utente che ha eseguito l'accesso dalla variabile
authe utilizzarlo per controllare a quali dati può accedere un utente.
Puoi consentire agli utenti di accedere alla tua app utilizzando più provider di autenticazione collegando le credenziali del provider di autenticazione a un account utente esistente.
Per disconnettere un utente, chiama
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. });