Autenticazione telefonica

L'autenticazione tramite telefono consente agli utenti di accedere a Firebase utilizzando il proprio telefono 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, incluso, a titolo esemplificativo, Firebase. Gli sviluppatori devono assicurarsi di disporre del consenso dell'utente finale appropriato prima di utilizzare il servizio di accesso mediante numero di telefono di Firebase Authentication.

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

Configurazione

Prima di iniziare con la verifica telefonica, assicurati di aver seguito questi passaggi:

  1. Attiva il telefono come metodo di accesso nella console Firebase.
  2. Android: se non hai ancora impostato l'hash SHA-1 della tua app nella console Firebase, fallo ora. Consulta la sezione Autenticazione del client per informazioni su come trovare l'hash SHA-1 della tua app.
  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à background per le notifiche remote. Per una spiegazione dettagliata di questo passaggio, consulta la documentazione relativa all'autenticazione telefonica Firebase iOS.
  4. Web: assicurati di aver aggiunto il dominio delle tue applicazioni nella console Firebase, in Domini di reindirizzamento OAuth.

Nota: l'accesso con il 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 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 esclusivamente:

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

Nativo: verifyPhoneNumber

Sulle piattaforme native, il numero di telefono dell'utente deve essere prima verificato, dopodiché l'utente può accedere o collegare il proprio account a 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 quattro 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 superamento della quota di SMS.
  3. codeSent: gestisci l'invio di un codice 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 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 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, a seconda del codice di errore, dovresti comunicare all'utente che si è verificato un problema.

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 restituiranno sempre un valore null).

Una volta attivato, è il momento giusto per aggiornare la UI dell'applicazione e chiedere all'utente di inserire il codice SMS che si aspetta. 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 nuovamente un nuovo messaggio SMS se è stato inviato di recente. Tuttavia, puoi ignorare questo comportamento richiamando nuovamente il metodo verifyPhoneNumber con il token di invio nell'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 maggiore sicurezza e prevenzione dello spam, agli utenti viene chiesto di dimostrare di essere umani completando un widget Google reCAPTCHA. Una volta confermato, verrà inviato il codice SMS.

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

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

Come altri flussi di accesso, un accesso riuscito attiverà tutti i listener dello stato di autenticazione a cui hai eseguito la sottoscrizione 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 viene visualizzato come widget invisibile quando viene attivato il flusso di accesso. Un widget "invisibile" viene visualizzato come modale a schermo intero 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 incorporato, specifica un ID elemento DOM nell'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 reCAPTCHA è stato completato dall'utente, 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 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 prova per i metodi verifyPhoneNumber o signInWithPhoneNumber, non verrà inviato alcun SMS. Puoi invece fornire il codice del test direttamente a PhoneAuthProvider o con il gestore dei risultati di conferma di signInWithPhoneNumber.