Аутентификация по телефону позволяет пользователям входить в Firebase, используя свой телефон в качестве аутентификатора. Пользователю (на указанный номер телефона) отправляется SMS-сообщение, содержащее уникальный код. После подтверждения кода пользователь может войти в Firebase.
Номера телефонов, которые конечные пользователи предоставляют для аутентификации, будут отправляться и храниться Google для повышения эффективности защиты от спама и злоупотреблений во всех сервисах Google, включая, помимо прочего, Firebase. Разработчики должны убедиться, что у них есть соответствующее согласие конечных пользователей, прежде чем использовать сервис аутентификации по номеру телефона Firebase.
Функция аутентификации по телефону Firebase поддерживается не во всех странах. Дополнительную информацию можно найти в разделе часто задаваемых вопросов (FAQ) .
Настраивать
Прежде чем приступить к аутентификации по телефону, убедитесь, что вы выполнили следующие шаги:
- Включите возможность входа по телефону в консоли Firebase .
- Android : Если вы еще не установили хеш SHA-1 для своего приложения в консоли Firebase , сделайте это. См. раздел «Аутентификация клиента» для получения информации о том, как найти хеш SHA-1 для вашего приложения.
- iOS : В Xcode включите push-уведомления для вашего проекта и убедитесь, что ваш ключ аутентификации APNs настроен для Firebase Cloud Messaging (FCM) . Кроме того, необходимо включить фоновые режимы для удаленных уведомлений. Подробное объяснение этого шага см. в документации Firebase iOS Phone Auth .
- Веб-версия : Убедитесь, что вы добавили домен вашего приложения в консоли Firebase в разделе «Домены перенаправления OAuth» .
Примечание : Вход по номеру телефона доступен только на реальных устройствах и в веб-браузере. Чтобы проверить процесс аутентификации на эмуляторах устройств, см. раздел «Тестирование» .
Использование
SDK аутентификации Firebase для Flutter предоставляет два отдельных способа авторизации пользователя с помощью номера телефона. Нативные платформы (например, Android и iOS) предоставляют иную функциональность для проверки номера телефона, чем веб-платформы, поэтому для каждой платформы существует два отдельных метода:
- Нативная платформа :
verifyPhoneNumber. - Веб-платформа :
signInWithPhoneNumber.
Native: verifyPhoneNumber
На нативных платформах сначала необходимо подтвердить номер телефона пользователя, после чего пользователь может либо войти в систему, либо связать свою учетную запись с помощью PhoneAuthCredential .
Сначала необходимо запросить у пользователя номер телефона. После этого вызовите метод verifyPhoneNumber() :
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: '+44 7123 123 456',
verificationCompleted: (PhoneAuthCredential credential) {},
verificationFailed: (FirebaseAuthException e) {},
codeSent: (String verificationId, int? resendToken) {},
codeAutoRetrievalTimeout: (String verificationId) {},
);
Вам необходимо обработать 4 отдельных функции обратного вызова, каждая из которых будет определять способ обновления пользовательского интерфейса приложения:
- Проверка завершена : автоматическая обработка SMS-кода на устройствах Android.
- verificationFailed : Обработка событий, приводящих к сбою, таких как недействительные номера телефонов или превышение квоты на SMS.
- codeSent : Обрабатывает событие, когда код был отправлен на устройство из Firebase; используется для запроса у пользователей ввода кода.
- codeAutoRetrievalTimeout : Обработка таймаута, возникающего при сбое автоматической обработки SMS-кодов.
Проверка завершена.
Этот обработчик будет вызываться только на устройствах Android, поддерживающих автоматическое определение SMS-кода.
Когда SMS-код доставлен на устройство, Android автоматически проверит его, не требуя от пользователя ручного ввода. В этом случае автоматически предоставляется объект PhoneAuthCredential , который можно использовать для входа в систему или привязки номера телефона пользователя.
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);
},
);
проверка не удалась
Если Firebase возвращает ошибку, например, из-за неверного номера телефона или превышения квоты SMS для проекта, обработчику будет отправлено исключение FirebaseAuthException . В этом случае, в зависимости от кода ошибки, вы должны сообщить пользователю о возникшей проблеме.
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
},
);
кодОтправлен
Когда Firebase отправляет SMS-код на устройство, этот обработчик срабатывает с verificationId и resendToken ( resendToken поддерживается только на устройствах Android, устройства iOS всегда будут возвращать значение null ).
После срабатывания сигнала будет уместно обновить пользовательский интерфейс приложения, чтобы предложить пользователю ввести ожидаемый SMS-код. После ввода SMS-кода вы можете объединить идентификатор подтверждения с SMS-кодом, чтобы создать новый объект 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);
},
);
По умолчанию Firebase не отправляет повторно SMS-сообщение, если оно было отправлено недавно. Однако вы можете изменить это поведение, повторно вызвав метод verifyPhoneNumber с токеном повторной отправки в качестве аргумента forceResendingToken . В случае успеха SMS-сообщение будет отправлено повторно.
codeAutoRetrievalTimeout
На устройствах Android, поддерживающих автоматическое разрешение SMS-кодов, этот обработчик будет вызываться, если устройство не разрешит SMS-сообщение автоматически в течение определенного периода времени. По истечении этого периода устройство больше не будет пытаться разрешить входящие сообщения.
По умолчанию устройство ожидает 30 секунд, однако это время можно изменить с помощью аргумента 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...
},
);
Веб-сайт: signInWithPhoneNumber
На веб-платформах пользователи могут войти в систему, подтвердив наличие доступа к телефону путем ввода SMS-кода, отправленного на указанный номер телефона. Для дополнительной безопасности и предотвращения спама пользователям предлагается подтвердить, что они являются людьми, пройдя проверку Google reCAPTCHA . После подтверждения будет отправлен SMS-код.
SDK Firebase Authentication для Flutter по умолчанию управляет виджетом reCAPTCHA, однако при необходимости предоставляет возможность управлять его отображением и настройкой. Для начала вызовите метод signInWithPhoneNumber , указав номер телефона.
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');
Вызов метода сначала запустит виджет reCAPTCHA. Пользователь должен пройти проверку, прежде чем будет отправлен SMS-код. После завершения вы можете авторизовать пользователя, передав SMS-код методу confirm в ответе ConfirmationResult :
UserCredential userCredential = await confirmationResult.confirm('123456');
Как и в других сценариях авторизации, успешный вход в систему активирует все обработчики состояния аутентификации, на которые вы подписались в своем приложении.
Настройка reCAPTCHA
Виджет reCAPTCHA представляет собой полностью управляемый процесс, обеспечивающий безопасность вашего веб-приложения.
Второй аргумент функции signInWithPhoneNumber принимает необязательный экземпляр RecaptchaVerifier , который можно использовать для управления виджетом. По умолчанию виджет будет отображаться как невидимый при запуске процесса авторизации. «Невидимый» виджет будет отображаться как полноэкранное модальное окно поверх вашего приложения.
Однако можно отобразить встроенный виджет, на который пользователю необходимо будет явно нажать для подтверждения своей личности.
Чтобы добавить встроенный виджет, укажите идентификатор DOM-элемента в аргументе container экземпляра ` RecaptchaVerifier . Элемент должен существовать и быть пустым, иначе будет выдана ошибка. Если аргумент container не указан, виджет будет отображаться как «невидимый».
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
container: 'recaptcha',
size: RecaptchaVerifierSize.compact,
theme: RecaptchaVerifierTheme.dark,
));
При желании вы можете изменить размер и тему оформления, настроив параметры size и theme , как показано выше.
Также можно отслеживать события, например, завершил ли пользователь проверку reCAPTCHA, истек ли срок действия reCAPTCHA или была ли выдана ошибка:
RecaptchaVerifier(
onSuccess: () => print('reCAPTCHA Completed!'),
onError: (FirebaseAuthException error) => print(error),
onExpired: () => print('reCAPTCHA Expired!'),
);
Тестирование
Firebase обеспечивает поддержку локального тестирования телефонных номеров:
- В консоли Firebase выберите поставщика аутентификации «Телефон» и щелкните раскрывающийся список «Номера телефонов для тестирования».
- Введите новый номер телефона (например
+44 7444 555666) и тестовый код (например,123456).
Если в методах verifyPhoneNumber или signInWithPhoneNumber указан тестовый номер телефона, SMS-сообщение фактически отправлено не будет. Вместо этого вы можете передать тестовый код непосредственно в PhoneAuthProvider или в обработчик результатов подтверждения метода signInWithPhoneNumber .