Если вы перешли на аутентификацию Firebase с Identity Platform, вы можете добавить многофакторную аутентификацию по SMS в свое приложение Flutter.
Многофакторная аутентификация (MFA) повышает безопасность вашего приложения. Хотя злоумышленники часто взламывают пароли и аккаунты социальных сетей, перехватить текстовое сообщение сложнее.
Прежде чем начать
Включите хотя бы одного провайдера, который поддерживает многофакторную аутентификацию. Каждый провайдер поддерживает MFA, за исключением телефонной аутентификации, анонимной аутентификации и Apple Game Center.
Убедитесь, что ваше приложение проверяет адреса электронной почты пользователей. MFA требует проверки адреса электронной почты. Это не позволяет злоумышленникам регистрироваться на сервисе с адресом электронной почты, которым они не владеют, а затем блокировать настоящего владельца, добавляя второй фактор.
Android : Если вы еще не установили хэш SHA-256 вашего приложения в консоли Firebase , сделайте это. См. раздел Аутентификация клиента для получения информации о поиске хэша SHA-256 вашего приложения.
iOS : В Xcode включите push-уведомления для вашего проекта и убедитесь, что ваш ключ аутентификации APN настроен с помощью Firebase Cloud Messaging (FCM) . Кроме того, необходимо включить фоновые режимы для удаленных уведомлений. Чтобы просмотреть подробное объяснение этого шага, просмотрите документацию Firebase iOS Phone Auth .
Веб : убедитесь, что вы добавили домен своего приложения в консоли Firebase в разделе Домены перенаправления OAuth .
Включение многофакторной аутентификации
Откройте страницу «Аутентификация» > «Метод входа» в консоли Firebase.
В разделе «Дополнительно» включите функцию «Многофакторная аутентификация по SMS» .
Вам также следует ввести номера телефонов, с которыми вы будете тестировать свое приложение. Хотя это необязательно, регистрация тестовых номеров телефонов настоятельно рекомендуется, чтобы избежать ограничения во время разработки.
Если вы еще не авторизовали домен своего приложения, добавьте его в список разрешенных на странице Аутентификация > Настройки консоли Firebase.
Выбор схемы зачисления
Вы можете выбрать, требует ли ваше приложение многофакторной аутентификации, а также как и когда регистрировать ваших пользователей. Некоторые общие шаблоны включают:
Зарегистрируйте второй фактор пользователя как часть регистрации. Используйте этот метод, если ваше приложение требует многофакторной аутентификации для всех пользователей.
Предложите возможность пропуска для регистрации второго фактора во время регистрации. Приложения, которые хотят поощрять, но не требовать многофакторную аутентификацию, могут предпочесть этот подход.
Предоставьте возможность добавлять второй фактор со страницы управления учетной записью или профилем пользователя, а не с экрана регистрации. Это минимизирует трение во время процесса регистрации, при этом оставляя многофакторную аутентификацию доступной для пользователей, чувствительных к безопасности.
Требуйте постепенного добавления второго фактора, когда пользователь захочет получить доступ к функциям с повышенными требованиями к безопасности.
Регистрация второго фактора
Чтобы зарегистрировать новый вторичный фактор для пользователя:
Повторно аутентифицируйте пользователя.
Попросите пользователя ввести свой номер телефона.
Получите многофакторный сеанс для пользователя:
final multiFactorSession = await user.multiFactor.getSession();
Проверьте номер телефона с помощью многофакторной сессии и обратных звонков:
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: (_) {}, );
После отправки SMS-кода попросите пользователя подтвердить код:
final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, );
Завершите регистрацию:
await user.multiFactor.enroll( PhoneMultiFactorGenerator.getAssertion( credential, ), );
В приведенном ниже коде показан полный пример регистрации второго фактора:
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: (_) {},
);
Поздравляем! Вы успешно зарегистрировали второй фактор аутентификации для пользователя.
Вход пользователей с использованием второго фактора
Чтобы войти в систему с двухфакторной аутентификацией по SMS:
Войдите в систему пользователя с его первым фактором, затем перехватите исключение
FirebaseAuthMultiFactorException
. Эта ошибка содержит решатель, который можно использовать для получения зарегистрированных вторых факторов пользователя. Она также содержит базовый сеанс, подтверждающий, что пользователь успешно прошел аутентификацию с его первым фактором.Например, если первым фактором пользователя был адрес электронной почты и пароль:
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 // ... }
Если у пользователя зарегистрировано несколько вторичных факторов, спросите его, какой из них использовать:
final session = e.resolver.session; final hint = e.resolver.hints[selectedHint];
Отправьте на телефон пользователя проверочное сообщение с подсказкой и сеансом многофакторной аутентификации:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: session, multiFactorInfo: hint, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // ... }, codeAutoRetrievalTimeout: (_) {}, );
Вызовите
resolver.resolveSignIn()
для завершения вторичной аутентификации: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); } }
В приведенном ниже коде показан полный пример входа пользователя с многофакторной аутентификацией:
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) {
...
}
Поздравляем! Вы успешно вошли в систему как пользователь, используя многофакторную аутентификацию.
Что дальше?
- Управляйте многофакторными пользователями программно с помощью Admin SDK.