Jeśli masz uaktualnione Uwierzytelnianie Firebase z Identity Platform, możesz dodać do aplikacji na Flatterze uwierzytelnianie wielopoziomowe przy użyciu SMS-ów.
Uwierzytelnianie wielopoziomowe (MFA) zwiększa bezpieczeństwo aplikacji. Osoby przeprowadzające ataki często przejmują hasła i konta społecznościowe, ale przechwycenie SMS-a jest trudniejsze.
Zanim zaczniesz
Włącz co najmniej 1 dostawcę, który obsługuje uwierzytelnianie wielopoziomowe. Każdy dostawca obsługuje MFA z wyjątkiem uwierzytelniania przez telefon, uwierzytelniania anonimowego i Apple Game Center.
Sprawdź, czy aplikacja weryfikuje adresy e-mail użytkowników. MFA wymaga potwierdzania adresu e-mail. Zapobiega to rejestrowaniu się hakerów w usłudze za pomocą adresu e-mail, który nie należy do nich, a następnie blokowaniu dostępu do konta prawdziwemu właścicielowi przez dodanie drugiego etapu weryfikacji.
iOS: w Xcode włącz powiadomienia push w projekcie i upewnij się, że klucz uwierzytelniania APNs jest skonfigurowany z Komunikacją w chmurze Firebase (FCM).
Musisz też włączyć tryby działania w tle w przypadku powiadomień zdalnych. Szczegółowe wyjaśnienie znajdziesz w dokumentacji Firebase iOS Phone Auth.
Android: jeśli nie zostało to jeszcze zrobione, podaj odcisk cyfrowy SHA-256 aplikacji:
W konsoli Firebase otwórz
Ustawienia > kartę Ogólne.Przewiń w dół do karty Twoje aplikacje, wybierz aplikację na Androida i dodaj odcisk cyfrowy SHA-256 w polu Odciski cyfrowe certyfikatu SHA.
Więcej informacji o tym, jak uzyskać odcisk cyfrowy SHA aplikacji, znajdziesz w sekcji Uwierzytelnianie klienta.
Internet: jeśli nie zostało to jeszcze zrobione, autoryzuj domenę aplikacji:
W konsoli Firebase otwórz kartę Zabezpieczenia> Uwierzytelnianie > Ustawienia.
W sekcji Autoryzowane domeny kliknij Dodaj domenę i dodaj swoją domenę.
Włączanie uwierzytelniania wielopoziomowego
W konsoli Firebase otwórz Bezpieczeństwo > Uwierzytelnianie.
Na karcie Metoda logowania w sekcji Zaawansowane włącz Uwierzytelnianie wielopoziomowe z użyciem SMS-ów.
Podaj też numery telefonów, których użyjesz do testowania aplikacji. Chociaż rejestracja numerów telefonów do testów jest opcjonalna, zdecydowanie ją zalecamy, ponieważ pozwoli uniknąć ograniczeń podczas programowania.
Jeśli jeszcze tego nie zrobiono, autoryzuj domenę aplikacji:
W konsoli Firebase otwórz Zabezpieczenia > Uwierzytelnianie > karta Ustawienia.
W sekcji Autoryzowane domeny kliknij Dodaj domenę i dodaj swoją domenę.
Wybieranie wzorca rejestracji
Możesz określić, czy Twoja aplikacja wymaga uwierzytelniania wielopoziomowego, a także jak i kiedy rejestrować użytkowników. Oto kilka typowych wzorców:
Zarejestruj drugi składnik użytkownika w ramach rejestracji. Użyj tej metody, jeśli aplikacja wymaga uwierzytelniania wielopoziomowego od wszystkich użytkowników.
Podczas rejestracji oferuj opcję pominięcia rejestracji drugiego składnika. Aplikacje, które chcą zachęcać do uwierzytelniania wielopoziomowego, ale nie wymagają go, mogą preferować to podejście.
Umożliwienie dodania drugiego czynnika na stronie zarządzania kontem lub profilem użytkownika, a nie na ekranie rejestracji. Minimalizuje to trudności podczas procesu rejestracji, a jednocześnie udostępnia uwierzytelnianie wielopoziomowe użytkownikom, którzy dbają o bezpieczeństwo.
Wymagaj dodania drugiego etapu weryfikacji, gdy użytkownik chce uzyskać dostęp do funkcji o zwiększonych wymaganiach dotyczących bezpieczeństwa.
Rejestrowanie drugiego składnika
Aby zarejestrować nowy czynnik dodatkowy dla użytkownika:
Ponownie uwierzytelnij użytkownika.
Poproś użytkownika o wpisanie numeru telefonu.
Uzyskiwanie sesji uwierzytelniania wielopoziomowego dla użytkownika:
final multiFactorSession = await user.multiFactor.getSession();Zweryfikuj numer telefonu za pomocą sesji uwierzytelniania wieloskładnikowego i wywołań zwrotnych:
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: (_) {}, );Gdy kod SMS zostanie wysłany, poproś użytkownika o jego weryfikację:
final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, );Dokończ rejestrację:
await user.multiFactor.enroll( PhoneMultiFactorGenerator.getAssertion( credential, ), );
Poniższy kod pokazuje kompletny przykład rejestracji drugiego czynnika:
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: (_) {},
);
Gratulacje! Udało Ci się zarejestrować drugi składnik uwierzytelniania dla użytkownika.
Logowanie użytkowników za pomocą drugiego składnika
Aby zalogować użytkownika za pomocą weryfikacji dwuskładnikowej przez SMS:
Zaloguj użytkownika za pomocą pierwszego czynnika, a następnie przechwyć wyjątek
FirebaseAuthMultiFactorException. Ten błąd zawiera obiekt resolver, którego możesz użyć do uzyskania zarejestrowanych drugich etapów weryfikacji użytkownika. Zawiera też sesję bazową, która potwierdza, że użytkownik został uwierzytelniony za pomocą pierwszego poziomu.Jeśli na przykład pierwszym składnikiem uwierzytelniania użytkownika był adres e-mail i hasło:
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 // ... }Jeśli użytkownik ma zarejestrowanych kilka składników dodatkowych, zapytaj go, którego z nich chce użyć:
final session = e.resolver.session; final hint = e.resolver.hints[selectedHint];Wyślij na telefon użytkownika wiadomość weryfikacyjną z podpowiedzią i sesją uwierzytelniania wielopoziomowego:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: session, multiFactorInfo: hint, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // ... }, codeAutoRetrievalTimeout: (_) {}, );Zadzwoń pod numer
resolver.resolveSignIn(), aby dokończyć uwierzytelnianie dodatkowe: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); } }
Poniższy kod przedstawia pełny przykład logowania użytkownika z uwierzytelnianiem wieloskładnikowym:
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) {
...
}
Gratulacje! Udało Ci się zalogować użytkownika za pomocą uwierzytelniania wielopoziomowego.
Co dalej?
- Zarządzaj użytkownikami korzystającymi z uwierzytelniania wieloskładnikowego programowo za pomocą pakietu Admin SDK.