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. Mentre gli utenti malintenzionati spesso compromettono 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 più fattori, ad eccezione dell'autenticazione telefonica, dell'autenticazione anonima e di Game Center di Apple.
Assicurati che la tua app verifichi le email degli utenti. L'autenticazione a più fattori richiede la verifica email. In questo modo, gli utenti malintenzionati non possono registrarsi a un servizio con un indirizzo email che non è di loro proprietà e bloccare il vero proprietario aggiungendo un secondo fattore.
Android: se non hai ancora impostato l'hash SHA-256 della tua app nella console Firebase, fallo ora. Consulta la sezione Autenticazione del client per informazioni su come trovare l'hash SHA-256 della tua app.
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.
Web: assicurati di aver aggiunto il dominio delle tue applicazioni nella console Firebase, in Domini di reindirizzamento OAuth.
Attivare l'autenticazione a più fattori
Apri la pagina Autenticazione > Metodo di accesso della console Firebase.
Nella sezione Avanzate, attiva Autenticazione a più fattori tramite SMS.
Devi 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 pattern di registrazione
Puoi scegliere se la tua app richiede l'autenticazione a più fattori e come e quando registrare gli utenti. Alcuni pattern comuni includono:
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.
Offrire 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, l'attrito durante la procedura di registrazione viene ridotto al minimo, pur rendendo l'autenticazione a più fattori disponibile per gli utenti sensibili alla sicurezza.
Richiedi l'aggiunta di un secondo fattore in modo incrementale quando l'utente vuole accedere a 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 di autenticazione 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 riportato di seguito 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 correttamente un secondo fattore di autenticazione per un utente.
Accesso degli utenti con un secondo fattore
Per accedere a un utente con la verifica via SMS a due fattori:
Accedi all'utente con il primo fattore, quindi rileva 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 ha eseguito l'autenticazione con il primo fattore.Ad esempio, se il primo fattore dell'utente era un'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 utilizzare:
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 di autenticazione 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 riportato di seguito 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 in modo programmatico con l'SDK Admin.