Autenticazione telefonica

L'autenticazione tramite telefono consente agli utenti di accedere a Firebase utilizzando il proprio telefono come token di autenticazione. All'utente (utilizzando il numero di telefono fornito) viene inviato un messaggio SMS contenente un codice univoco. Una volta autorizzato il codice, l'utente può accedere a Firebase.

I numeri di telefono forniti dagli utenti finali per l'autenticazione verranno inviati e archiviati da Google per migliorare la prevenzione di spam e abusi nel servizio Google, incluso, a titolo esemplificativo, Firebase. Gli sviluppatori devono assicurarsi di disporre del consenso appropriato dell'utente finale prima di utilizzare il servizio di accesso tramite numero di telefono di Firebase Authentication.authentication

L'autenticazione telefonica di Firebase non è supportata in tutti i paesi. Per ulteriori informazioni, consulta le Domande frequenti.

Configurazione

Prima di iniziare con l'autenticazione telefonica, assicurati di aver seguito questi passaggi:

  1. Abilita il telefono come metodo di accesso nella Console Firebase.
  2. Android: se non l'hai ancora fatto, imposta l'hash SHA-1 della tua app nella Console Firebase. Consulta la sezione Autenticazione del client per informazioni su come trovare l'hash SHA-1 della tua app.
  3. iOS: in Xcode, abilita le notifiche push per il tuo progetto e assicurati che la chiave di autenticazione APN sia configurata con Firebase Cloud Messaging (FCM). Inoltre, devi attivare le modalità in background per le notifiche remote. Per una spiegazione dettagliata di questo passaggio, consulta la documentazione di Firebase Phone Auth per iOS.
  4. Web: assicurati di aver aggiunto il dominio delle tue applicazioni nella Console Firebase, in Domini di reindirizzamento OAuth.

Nota: l'accesso con numero di telefono è disponibile solo per l'utilizzo su dispositivi reali e sul web. Per testare il flusso di autenticazione sugli emulatori di dispositivi, consulta la sezione Test.

Utilizzo

L'SDK Firebase Authentication per Flutter offre due modi per consentire a un utente di accedere con il proprio numero di telefono. Le piattaforme native (ad es. Android e iOS) forniscono funzionalità diverse per la convalida di un numero di telefono rispetto al web, pertanto esistono due metodi esclusivamente per ogni piattaforma:

  • Piattaforma nativa: verifyPhoneNumber.
  • Piattaforma web: signInWithPhoneNumber.

Nativo: verifyPhoneNumber

Sulle piattaforme native, il numero di telefono dell'utente deve prima essere verificato, dopodiché l'utente può accedere o collegare il proprio account con un PhoneAuthCredential.

Innanzitutto, devi chiedere all'utente il suo numero di telefono. Una volta fornito, chiama il metodo verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

Devi gestire quattro callback separati, ognuno dei quali determina in che modo aggiornare l'interfaccia utente dell'applicazione:

  1. verificationCompleted: gestione automatica del codice SMS sui dispositivi Android.
  2. verificationFailed: gestisce gli eventi di errore, ad esempio numeri di telefono non validi o se la quota di SMS è stata superata.
  3. codeSent: gestisce il momento in cui un codice è stato inviato al dispositivo da Firebase, utilizzato per chiedere agli utenti di inserire il codice.
  4. codeAutoRetrievalTimeout: gestisce un timeout quando la gestione automatica del codice SMS non va a buon fine.

verificationCompleted

Questo gestore verrà chiamato solo sui dispositivi Android che supportano la risoluzione automatica del codice SMS.

Quando il codice SMS viene inviato al dispositivo, Android lo verifica automaticamente senza richiedere all'utente di inserirlo manualmente. Se si verifica questo evento, viene fornito automaticamente un PhoneAuthCredential che può essere utilizzato per accedere con il numero di telefono dell'utente o collegarlo.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

verificationFailed

Se Firebase restituisce un errore, ad esempio per un numero di telefono errato o se la quota di SMS per il progetto è stata superata, a questo gestore verrà inviato un FirebaseAuthException. In questo caso, dovrai comunicare all'utente che si è verificato un problema, a seconda del codice di errore.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

codeSent

Quando Firebase invia un codice SMS al dispositivo, questo gestore viene attivato con verificationId e resendToken (resendToken è supportato solo sui dispositivi Android, mentre i dispositivi iOS restituiranno sempre un valore null).

Una volta attivato, è un buon momento per aggiornare l'interfaccia utente dell'applicazione in modo da chiedere all'utente di inserire il codice SMS che sta aspettando. Una volta inserito il codice SMS, puoi combinare l'ID verifica con il codice SMS per creare un nuovo PhoneAuthCredential:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

Per impostazione predefinita, Firebase non invia di nuovo un nuovo messaggio SMS se è stato inviato di recente. Tuttavia, puoi ignorare questo comportamento richiamando nuovamente il metodo verifyPhoneNumber con il token di invio nuovamente all'argomento forceResendingToken. Se l'operazione va a buon fine, il messaggio verrà inviato di nuovo.

codeAutoRetrievalTimeout

Sui dispositivi Android che supportano la risoluzione automatica del codice SMS, questo gestore verrà chiamato se il dispositivo non ha risolto automaticamente un messaggio SMS entro un determinato periodo di tempo. Una volta trascorso il periodo di tempo, il dispositivo non tenterà più di risolvere i messaggi in entrata.

Per impostazione predefinita, il dispositivo attende 30 secondi, ma questo valore può essere personalizzato con l'argomento timeout:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

Web: signInWithPhoneNumber

Sulle piattaforme web, gli utenti possono accedere confermando di avere accesso a uno smartphone inserendo il codice SMS inviato al numero di telefono fornito. Per maggiore sicurezza e prevenzione dello spam, agli utenti viene chiesto di dimostrare di essere persone reali completando un widget Google reCAPTCHA. Una volta confermata, verrà inviato il codice SMS.

L'SDK Firebase Authentication per Flutter gestisce il widget reCAPTCHA immediatamente, per impostazione predefinita, ma offre il controllo su come viene visualizzato e configurato, se necessario. Per iniziare, chiama il metodo signInWithPhoneNumber con il numero di telefono.

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

La chiamata al metodo attiverà prima la visualizzazione del widget reCAPTCHA. L'utente deve completare il test prima che venga inviato un codice SMS. Al termine, puoi far accedere l'utente fornendo il codice SMS al metodo confirm nella risposta ConfirmationResult risolta:

UserCredential userCredential = await confirmationResult.confirm('123456');

Come per altri flussi di accesso, un accesso riuscito attiverà tutti gli ascoltatori dello stato di autenticazione che hai sottoscritto nell'intera applicazione.

Configurazione reCAPTCHA

Il widget reCAPTCHA è un flusso completamente gestito che fornisce sicurezza alla tua applicazione web.

Il secondo argomento di signInWithPhoneNumber accetta un'istanza facoltativa di RecaptchaVerifier che può essere utilizzata per gestire il widget. Per impostazione predefinita, il widget viene visualizzato come invisibile quando viene attivato il flusso di accesso. Un widget "invisibile" verrà visualizzato come finestra modale a schermo intero sopra l'applicazione.

Tuttavia, è possibile mostrare un widget in linea che l'utente deve premere esplicitamente per effettuare la verifica.

Per aggiungere un widget in linea, specifica un ID elemento DOM all'argomento container dell'istanza RecaptchaVerifier. L'elemento deve esistere ed essere vuoto, altrimenti verrà generato un errore. Se non viene fornito alcun argomento container, il widget verrà visualizzato come "invisibile".

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

Facoltativamente, puoi modificare le dimensioni e il tema personalizzando gli argomenti size e theme come mostrato sopra.

È anche possibile ascoltare eventi, ad esempio se il reCAPTCHA è stato completato dall'utente, se è scaduto o se è stato generato un errore:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

Test

Firebase fornisce assistenza per il test locale dei numeri di telefono:

  1. Nella console Firebase, seleziona il provider di autenticazione "Telefono" e fai clic sul menu a discesa "Numeri di telefono per i test".
  2. Inserisci un nuovo numero di telefono (ad es. +44 7444 555666) e un codice di test (ad es. 123456).

Se fornisci un numero di telefono di prova ai metodi verifyPhoneNumber o signInWithPhoneNumber, non verrà inviato alcun SMS. Puoi invece fornire il codice di test direttamente a PhoneAuthProvider o al gestore dei risultati di conferma di signInWithPhoneNumber.