Autenticazione telefonica

L'autenticazione telefonica consente agli utenti di accedere a Firebase utilizzando il proprio smartphone come autenticatore. All'utente viene inviato un messaggio SMS (utilizzando il numero di telefono fornito) 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 dello spam e dei comportamenti illeciti nei servizi Google, inclusi, a titolo esemplificativo, Firebase. Gli sviluppatori devono assicurarsi di avere il consenso appropriato dell'utente finale prima di utilizzare il servizio di accesso mediante numero di telefono di Firebase Authentication.autenticazione

Firebase Phone Authentication non è supportato in tutti i paesi. Per ulteriori informazioni, consulta le Domande frequenti.

Configurazione

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

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

Nota: l'accesso mediante numero di telefono è disponibile solo 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 distinti 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 per ogni piattaforma in esclusiva:

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

Nativo: verifyPhoneNumber

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

Per prima cosa, 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 4 callback separati, ognuno dei quali determinerà come aggiornare l'interfaccia utente dell'applicazione:

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

verificationCompleted

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

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

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, chiederai all'utente se 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 un verificationId e un resendToken (un resendToken è supportato solo sui dispositivi Android, i dispositivi iOS restituiscono sempre un valore null).

Una volta attivato, è un buon momento per aggiornare l'interfaccia utente dell'applicazione per chiedere all'utente di inserire il codice SMS che si aspetta. Una volta inserito il codice SMS, puoi combinarlo con l'ID di verifica 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 invierà di nuovo un nuovo messaggio SMS se è stato inviato di recente. Tuttavia, puoi ignorare questo comportamento richiamando di nuovo il metodo verifyPhoneNumber con il token di invio di nuovo all'argomento forceResendingToken. Se l'operazione va a buon fine, il messaggio SMS 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 arrivo.

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 un telefono inserendo il codice SMS inviato al numero di telefono fornito. Per una maggiore sicurezza e prevenzione dello spam, agli utenti viene chiesto di dimostrare di essere umani completando un widget Google reCAPTCHA. Una volta confermato, il codice SMS verrà inviato.

L'SDK Firebase Authentication per Flutter gestisce il widget reCAPTCHA immediatamente per impostazione predefinita, ma fornisce 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 del metodo attiverà innanzitutto la visualizzazione del widget reCAPTCHA. L'utente deve completare il test prima che venga inviato un codice SMS. Una volta completato, puoi consentire all'utente di accedere fornendo il codice SMS al metodo confirm nella risposta ConfirmationResult risolta:

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

Come per gli altri flussi di accesso, un accesso riuscito attiverà tutti i listener dello stato di autenticazione a cui hai sottoscritto l'abbonamento nell'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 RecaptchaVerifier facoltativa che può essere utilizzata per gestire il widget. Per impostazione predefinita, il widget verrà visualizzato come widget invisibile quando viene attivato il flusso di accesso. Un widget "invisibile" verrà visualizzato come modale a pagina intera sopra l'applicazione.

Tuttavia, è possibile visualizzare un widget in linea che l'utente deve premere esplicitamente per verificare la propria identità.

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,
));

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

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

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

Test

Firebase fornisce il supporto 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 test ai metodi verifyPhoneNumber o signInWithPhoneNumber, non verrà inviato alcun SMS. In alternativa, puoi fornire il codice di test direttamente a PhoneAuthProvider o con il gestore dei risultati di conferma di signInWithPhoneNumber.