Если вы перешли на Firebase Authentication with Identity Platform, то можете добавить в приложение многофакторную аутентификацию (MFA) с использованием одноразовых кодов на основе времени (TOTP).
Firebase Authentication with Identity Platform позволяет использовать TOTP в качестве дополнительного фактора для МФА. Когда вы включите эту функцию, пользователи, пытающиеся войти в ваше приложение, увидят запрос на ввод TOTP. Для этого им нужно использовать приложение для аутентификации, способное генерировать действительные коды TOTP, например Google Authenticator.
Подготовка
Включите хотя бы одного поставщика, поддерживающего МФА. Обратите внимание, что все поставщики, кроме перечисленных ниже, поддерживают многофакторную аутентификацию:
- Аутентификация по телефону
- Анонимная аутентификация
- Специальные токены аутентификации
- Apple Game Center
Убедитесь, что ваше приложение проверяет адреса электронной почты пользователей. Для МФА требуется подтверждение адреса электронной почты. Это не позволяет злоумышленникам регистрироваться в сервисе с чужим адресом электронной почты, а затем блокировать доступ к нему для настоящего владельца, добавляя второй фактор.
Если вы ещё этого не сделали, установите Firebase Apple SDK.
Многофакторная аутентификация с помощью TOTP поддерживается только в Apple SDK версии 10.12.0 и выше и только на iOS.
Включить МФА с TOTP
Чтобы включить TOTP в качестве второго фактора, используйте Admin SDK или вызовите конечную точку REST для конфигурации проекта.
Чтобы использовать Admin SDK, выполните следующие действия:
Если вы ещё этого не сделали, установите Firebase Admin Node.js SDK.
Многофакторная аутентификация с помощью TOTP поддерживается только в Firebase Admin Node.js SDK версии 11.6.0 и выше.
Выполните следующую команду:
import { getAuth } from 'firebase-admin/auth'; getAuth().projectConfigManager().updateProjectConfig( { multiFactorConfig: { providerConfigs: [{ state: "ENABLED", totpProviderConfig: { adjacentIntervals: NUM_ADJ_INTERVALS } }] } })Замените следующее:
NUM_ADJ_INTERVALS– количество смежных интервалов временного окна, из которых принимаются TOTP (от 0 до 10). Значение по умолчанию – 5.Принцип работы TOTP заключается в том, что когда две стороны (проверяющий и проверяемый) генерируют одноразовые пароли в течение одного и того же временного окна (обычно 30 секунд), они генерируют один и тот же пароль. Однако, чтобы учесть расхождение часов между сторонами и время ответа человека, вы можете настроить сервис TOTP так, чтобы он также принимал TOTP из соседних окон.
Чтобы включить TOTP МФА с помощью REST API, выполните следующую команду:
curl -X PATCH "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=mfa" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-H "X-Goog-User-Project: PROJECT_ID" \
-d \
'{
"mfa": {
"providerConfigs": [{
"state": "ENABLED",
"totpProviderConfig": {
"adjacentIntervals": NUM_ADJ_INTERVALS
}
}]
}
}'
Замените следующее:
PROJECT_ID– идентификатор проекта.NUM_ADJ_INTERVALS: количество временных интервалов (от 0 до 10). Значение по умолчанию – 5.Принцип работы TOTP заключается в том, что когда две стороны (проверяющий и проверяемый) генерируют одноразовые пароли в течение одного и того же временного окна (обычно 30 секунд), они генерируют один и тот же пароль. Однако, чтобы учесть расхождение часов между сторонами и время ответа человека, вы можете настроить сервис TOTP так, чтобы он также принимал TOTP из соседних окон.
Выберите шаблон регистрации
Вы можете выбрать, требуется ли для вашего приложения многофакторная аутентификация, а также как и когда регистрировать пользователей. Вот некоторые распространенные шаблоны:
Зарегистрируйте второй фактор пользователя в рамках регистрации. Используйте этот метод, если в вашем приложении требуется многофакторная аутентификация для всех пользователей.
Предложите пользователям добавить второй фактор при регистрации, но оставьте возможность пропустить этот шаг. Если вы хотите поощрять, но не требовать многофакторную аутентификацию в своем приложении, вы можете использовать этот подход.
Предоставьте возможность добавить второй фактор на странице управления аккаунтом или профилем пользователя, а не на экране регистрации. Это сводит к минимуму трения в процессе регистрации, в то же время делая многофакторную аутентификацию доступной для пользователей, заботящихся о безопасности.
Требовать добавления второго фактора, когда пользователь хочет получить доступ к функциям с повышенными требованиями к безопасности.
Как зарегистрировать пользователей в МФА на основе TOTP
После того как вы включите TOTP МФА в качестве второго фактора для приложения, реализуйте клиентскую логику, чтобы зарегистрировать пользователей в TOTP МФА:
Попросите пользователя повторно пройти аутентификацию.
Сгенерируйте секретный ключ TOTP для аутентифицированного пользователя:
// Generate a TOTP secret. guard let mfaSession = try? await currentUser.multiFactor.session() else { return } guard let totpSecret = try? await TOTPMultiFactorGenerator.generateSecret(with: mfaSession) else { return } // Display the secret to the user and prompt them to enter it into their // authenticator app. (See the next step.)Покажите секретный ключ пользователю и попросите его ввести этот ключ в приложении для аутентификации.
// Display this key: let secret = totpSecret.sharedSecretKey()Вы можете не только показать секретный ключ, но и попробовать автоматически добавить его в приложение для аутентификации, установленное на устройстве по умолчанию. Для этого сгенерируйте URI ключа, совместимого с Google Authenticator, и передайте его в
openInOTPApp(withQRCodeURL:):let otpAuthUri = totpSecret.generateQRCodeURL( withAccountName: currentUser.email ?? "default account", issuer: "Your App Name") totpSecret.openInOTPApp(withQRCodeURL: otpAuthUri)После того как пользователь добавит секретный ключ в приложение для аутентификации, оно начнет генерировать TOTP.
Предложите пользователю ввести TOTP, показанный в приложении для аутентификации, и используйте его, чтобы завершить регистрацию МФА:
// Ask the user for a verification code from the authenticator app. let verificationCode = // Code from user input. // Finalize the enrollment. let multiFactorAssertion = TOTPMultiFactorGenerator.assertionForEnrollment( with: totpSecret, oneTimePassword: verificationCode) do { try await currentUser.multiFactor.enroll( with: multiFactorAssertion, displayName: "TOTP") } catch { // Wrong or expired OTP. Re-prompt the user. }
Как настроить вход пользователей с использованием второго фактора
Чтобы пользователи могли входить в аккаунт с помощью МФА TOTP, используйте следующий код:
Вызовите один из методов
signIn(with...:)-, как если бы вы не использовали МФА (например,signIn(withEmail:password:)). Если метод выдает ошибку с кодомsecondFactorRequired, запустите процесс МФА в приложении.do { let authResult = try await Auth.auth().signIn(withEmail: email, password: password) // If the user is not enrolled with a second factor and provided valid // credentials, sign-in succeeds. // (If your app requires MFA, this could be considered an error // condition, which you would resolve by forcing the user to enroll a // second factor.) // ... } catch let error as AuthErrorCode where error.code == .secondFactorRequired { // Initiate your second factor sign-in flow. (See next step.) // ... } catch { // Other auth error. throw error }В процессе МФА в приложении пользователю сначала должно быть предложено выбрать второй фактор, который он хочет использовать. Чтобы получить список поддерживаемых вторых факторов, проверьте свойство
hintsэкземпляраMultiFactorResolver:let mfaKey = AuthErrorUserInfoMultiFactorResolverKey guard let resolver = error.userInfo[mfaKey] as? MultiFactorResolver else { return } let enrolledFactors = resolver.hints.map(\.displayName)Если пользователь выбирает TOTP, предложите ему ввести TOTP, показанный в приложении для аутентификации, и использовать его для входа:
let multiFactorInfo = resolver.hints[selectedIndex] switch multiFactorInfo.factorID { case TOTPMultiFactorID: let otpFromAuthenticator = // OTP typed by the user. let assertion = TOTPMultiFactorGenerator.assertionForSignIn( withEnrollmentID: multiFactorInfo.uid, oneTimePassword: otpFromAuthenticator) do { let authResult = try await resolver.resolveSignIn(with: assertion) } catch { // Wrong or expired OTP. Re-prompt the user. } default: return }
Как отменить регистрацию в TOTP MFA
В этом разделе описывается, как обрабатывать отмену регистрации пользователя в TOTP МФА.
Если пользователь зарегистрировал несколько способов МФА и отменил регистрацию последнего включенного способа, он получит auth/user-token-expired и будет выполнен выход из аккаунта. Пользователю нужно будет снова войти в аккаунт и подтвердить свои учетные данные, например адрес электронной почты и пароль.
Чтобы отменить регистрацию пользователя, обработать ошибку и запустить повторную аутентификацию, используйте следующий код:
guard let currentUser = Auth.auth().currentUser else { return }
// Prompt the user to select a factor to unenroll, from this array:
currentUser.multiFactor.enrolledFactors
// ...
// Unenroll the second factor.
let multiFactorInfo = currentUser.multiFactor.enrolledFactors[selectedIndex]
do {
try await currentUser.multiFactor.unenroll(with: multiFactorInfo)
} catch let error as AuthErrorCode where error.code == .invalidUserToken {
// Second factor unenrolled, but the user was signed out. Re-authenticate
// them.
}
Дальнейшие действия
- Управляйте пользователями с многофакторной аутентификацией программно с помощью Admin SDK.