Se hai eseguito l'upgrade a Firebase Authentication con Identity Platform, puoi aggiungere l'autenticazione a più fattori via SMS alla tua app Flutter.
L'autenticazione a più fattori (MFA) aumenta la sicurezza della tua app. Sebbene gli utenti malintenzionati spesso compromettano password e account social, intercettare un messaggio di testo è più difficile.
Prima di iniziare
Attiva almeno un provider che supporti l'autenticazione a più fattori. Tutti i provider supportano l'autenticazione a due fattori, tranne l'autenticazione telefonica, l'autenticazione anonima e Game Center di Apple.
Assicurati che la tua app verifichi le email degli utenti. La verifica in due passaggi richiede la verifica email. In questo modo, gli utenti malintenzionati non possono registrarsi a un servizio con un indirizzo email che non possiedono e bloccare il proprietario reale aggiungendo un secondo fattore.
Android: se non hai ancora impostato l'hash SHA-256 della tua app nella console Firebase, fallo. Consulta la sezione Autenticazione del client per informazioni su come trovare l'hash SHA-256 della tua app.
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.
Web: assicurati di aver aggiunto il dominio delle tue applicazioni nella Console Firebase, in Domini di reindirizzamento OAuth.
Attivazione dell'autenticazione a più fattori
Apri la pagina Autenticazione > Metodo di accesso della Console Firebase.
Nella sezione Avanzate, attiva l'autenticazione a più fattori tramite SMS.
Dovresti anche inserire i numeri di telefono con cui testerai l'app. Sebbene sia facoltativo, ti consigliamo vivamente di registrare i numeri di telefono per i test al fine di evitare limitazioni durante lo sviluppo.
Se non hai ancora autorizzato il dominio della tua app, aggiungilo alla lista consentita nella pagina Autenticazione > Impostazioni della console Firebase.
Scegliere un modello di registrazione
Puoi scegliere se la tua app richiede l'autenticazione a più fattori, nonché come e quando registrare gli utenti. Ecco alcuni pattern comuni:
Registra il secondo fattore dell'utente durante la registrazione. Utilizza questo metodo se la tua app richiede l'autenticazione a più fattori per tutti gli utenti.
Offri un'opzione ignorabile per registrare un secondo fattore durante la registrazione. Le app che vogliono incoraggiare, ma non richiedere, l'autenticazione a più fattori potrebbero preferire questo approccio.
Offri la possibilità di aggiungere un secondo fattore dalla pagina di gestione dell'account o del profilo dell'utente, anziché dalla schermata di registrazione. In questo modo, le difficoltà durante la procedura di registrazione vengono ridotte al minimo, pur mantenendo l'autenticazione a più fattori disponibile per gli utenti attenti alla sicurezza.
Richiedi l'aggiunta di un secondo fattore in modo incrementale quando l'utente vuole accedere alle funzionalità con requisiti di sicurezza più elevati.
Registrazione di un secondo fattore
Per registrare un nuovo fattore secondario per un utente:
Esegui nuovamente l'autenticazione dell'utente.
Chiedi all'utente di inserire il proprio numero di telefono.
Ottieni una sessione con autenticazione a più fattori per l'utente:
final multiFactorSession = await user.multiFactor.getSession();
Verifica il numero di telefono con una sessione a più fattori e i tuoi callback:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: multiFactorSession, phoneNumber: phoneNumber, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // The SMS verification code has been sent to the provided phone number. // ... }, codeAutoRetrievalTimeout: (_) {}, );
Una volta inviato il codice SMS, chiedi all'utente di verificarlo:
final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, );
Completa la registrazione:
await user.multiFactor.enroll( PhoneMultiFactorGenerator.getAssertion( credential, ), );
Il codice seguente mostra un esempio completo di registrazione di un secondo fattore:
final session = await user.multiFactor.getSession();
final auth = FirebaseAuth.instance;
await auth.verifyPhoneNumber(
multiFactorSession: session,
phoneNumber: phoneController.text,
verificationCompleted: (_) {},
verificationFailed: (_) {},
codeSent: (String verificationId, int? resendToken) async {
// See `firebase_auth` example app for a method of retrieving user's sms code:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
final smsCode = await getSmsCodeFromUser(context);
if (smsCode != null) {
// Create a PhoneAuthCredential with the code
final credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
try {
await user.multiFactor.enroll(
PhoneMultiFactorGenerator.getAssertion(
credential,
),
);
} on FirebaseAuthException catch (e) {
print(e.message);
}
}
},
codeAutoRetrievalTimeout: (_) {},
);
Complimenti! Hai registrato un secondo fattore di autenticazione per un utente.
Accedere con un secondo fattore
Per consentire a un utente di accedere con la verifica SMS a due fattori:
Fai accedere l'utente con il primo fattore, quindi recupera l'eccezione
FirebaseAuthMultiFactorException
. Questo errore contiene un resolver che puoi utilizzare per ottenere i secondi fattori registrati dell'utente. Contiene anche una sessione sottostante che dimostra che l'utente si è autenticato correttamente con il primo fattore.Ad esempio, se il primo fattore dell'utente era un indirizzo email e una password:
try { await _auth.signInWithEmailAndPassword( email: emailController.text, password: passwordController.text, ); // User is not enrolled with a second factor and is successfully // signed in. // ... } on FirebaseAuthMultiFactorException catch (e) { // The user is a multi-factor user. Second factor challenge is required final resolver = e.resolver // ... }
Se l'utente ha registrato più fattori secondari, chiedigli quale usare:
final session = e.resolver.session; final hint = e.resolver.hints[selectedHint];
Invia un messaggio di verifica al telefono dell'utente con il suggerimento e la sessione a più fattori:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: session, multiFactorInfo: hint, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // ... }, codeAutoRetrievalTimeout: (_) {}, );
Chiama il numero
resolver.resolveSignIn()
per completare l'autenticazione secondaria:final smsCode = await getSmsCodeFromUser(context); if (smsCode != null) { // Create a PhoneAuthCredential with the code final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, ); try { await e.resolver.resolveSignIn( PhoneMultiFactorGenerator.getAssertion(credential) ); } on FirebaseAuthException catch (e) { print(e.message); } }
Il codice seguente mostra un esempio completo di accesso di un utente con autenticazione a più fattori:
try {
await _auth.signInWithEmailAndPassword(
email: emailController.text,
password: passwordController.text,
);
} on FirebaseAuthMultiFactorException catch (e) {
setState(() {
error = '${e.message}';
});
final firstHint = e.resolver.hints.first;
if (firstHint is! PhoneMultiFactorInfo) {
return;
}
await FirebaseAuth.instance.verifyPhoneNumber(
multiFactorSession: e.resolver.session,
multiFactorInfo: firstHint,
verificationCompleted: (_) {},
verificationFailed: (_) {},
codeSent: (String verificationId, int? resendToken) async {
// See `firebase_auth` example app for a method of retrieving user's sms code:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
final smsCode = await getSmsCodeFromUser(context);
if (smsCode != null) {
// Create a PhoneAuthCredential with the code
final credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
try {
await e.resolver.resolveSignIn(
PhoneMultiFactorGenerator.getAssertion(
credential,
),
);
} on FirebaseAuthException catch (e) {
print(e.message);
}
}
},
codeAutoRetrievalTimeout: (_) {},
);
} catch (e) {
...
}
Complimenti! Hai eseguito l'accesso a un utente utilizzando l'autenticazione a più fattori.
Passaggi successivi
- Gestisci gli utenti con autenticazione a più fattori programmaticamente con l'SDK Admin.