Если вы перешли на Firebase Authentication with Identity Platform , вы можете добавить в свое приложение многофакторную аутентификацию (MFA) с одноразовым паролем (TOTP) с ограниченным по времени сроком действия.
Firebase Authentication with Identity Platform позволяет использовать TOTP в качестве дополнительного фактора многофакторной аутентификации (MFA). При включении этой функции пользователи, пытающиеся войти в ваше приложение, видят запрос TOTP. Для его создания необходимо использовать приложение-аутентификатор, способное генерировать действительные коды TOTP, например, Google Authenticator .
Прежде чем начать
Включите хотя бы одного поставщика, поддерживающего MFA. Обратите внимание, что MFA поддерживают все поставщики, за исключением следующих:
- Авторизация по телефону
- Анонимная аутентификация
- Пользовательские токены авторизации
- Apple Game Center
Убедитесь, что ваше приложение проверяет адреса электронной почты пользователей. Многофакторная аутентификация (MFA) требует подтверждения адреса электронной почты. Это предотвращает возможность злоумышленников регистрироваться в сервисе с адресом электронной почты, которым они не владеют, а затем блокировать доступ к фактическому владельцу адреса электронной почты, добавляя второй фактор.
Если вы еще этого не сделали, установите Firebase JavaScript SDK .
TOTP MFA поддерживается только в модульном Web SDK версии v9.19.1 и выше.
Включить TOTP MFA
Чтобы включить TOTP в качестве второго фактора, используйте Admin SDK или вызовите конечную точку REST конфигурации проекта.
Чтобы использовать Admin SDK , выполните следующие действия:
Если вы еще этого не сделали, установите Firebase Admin Node.js SDK .
TOTP MFA поддерживается только в 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, от нуля до десяти. Значение по умолчанию — пять.Принцип работы TOTP заключается в том, что когда две стороны (доказывающая сторона и валидатор) генерируют одноразовые пароли в течение одного и того же временного интервала (обычно 30 секунд), они генерируют один и тот же пароль. Однако, чтобы компенсировать разницу во времени между сторонами и время ответа человека, вы можете настроить службу TOTP так, чтобы она принимала TOTP и из смежных временных интервалов.
Чтобы включить TOTP MFA с помощью 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
: Количество интервалов временного окна, от нуля до десяти. Значение по умолчанию — пять.Принцип работы TOTP заключается в том, что когда две стороны (доказывающая сторона и валидатор) генерируют одноразовые пароли в течение одного и того же временного интервала (обычно 30 секунд), они генерируют один и тот же пароль. Однако, чтобы компенсировать разницу во времени между сторонами и время ответа человека, вы можете настроить службу TOTP так, чтобы она принимала TOTP и из смежных временных интервалов.
Выберите схему регистрации
Вы можете выбрать, требуется ли вашему приложению многофакторная аутентификация, а также как и когда регистрировать пользователей. Вот некоторые распространённые шаблоны:
Включите второй фактор аутентификации пользователя в процесс регистрации. Используйте этот метод, если ваше приложение требует многофакторной аутентификации для всех пользователей.
Предложите возможность пропуска второго фактора аутентификации при регистрации. Если вы хотите поощрять, но не требовать многофакторную аутентификацию в своём приложении, вы можете использовать этот подход.
Предоставьте возможность добавления второго фактора на странице управления учётной записью или профилем пользователя, а не на экране регистрации. Это минимизирует сложности в процессе регистрации, сохраняя при этом доступность многофакторной аутентификации для пользователей, которым важны вопросы безопасности.
Требуйте постепенного добавления второго фактора, когда пользователь захочет получить доступ к функциям с повышенными требованиями к безопасности.
Регистрация пользователей в TOTP MFA
После включения TOTP MFA в качестве второго фактора для вашего приложения реализуйте клиентскую логику для регистрации пользователей в TOTP MFA:
Импортируйте необходимые классы и функции MFA:
import { multiFactor, TotpMultiFactorGenerator, TotpSecret, getAuth, } from "firebase/auth";
Повторно аутентифицируйте пользователя.
Сгенерируйте секрет TOTP для аутентифицированного пользователя:
// Generate a TOTP secret. const multiFactorSession = await multiFactor(currentUser).getSession(); const totpSecret = await TotpMultiFactorGenerator.generateSecret( multiFactorSession );
Покажите секрет пользователю и предложите ввести его в приложение-аутентификатор.
Многие приложения для аутентификации позволяют пользователям быстро добавлять новые секреты TOTP, сканируя QR-код, представляющий собой URI ключа, совместимый с Google Authenticator . Чтобы сгенерировать QR-код, создайте URI с помощью функции
generateQrCodeUrl()
, а затем закодируйте его с помощью библиотеки QR-кодов по вашему выбору. Например:const totpUri = totpSecret.generateQrCodeUrl( currentUser.email, "Your App's Name" ); await QRExampleLib.toCanvas(totpUri, qrElement);
Независимо от того, отображаете ли вы QR-код, всегда отображайте секретный ключ для поддержки приложений-аутентификаторов, которые не могут считывать QR-коды:
// Also display this key: const secret = totpSecret.secretKey;
После того как пользователь добавит свой секрет в приложение-аутентификатор, оно начнет генерировать TOTP.
Предложите пользователю ввести TOTP, отображаемый в приложении аутентификации, и использовать его для завершения регистрации MFA:
// Ask the user for a verification code from the authenticator app. const verificationCode = // Code from user input. // Finalize the enrollment. const multiFactorAssertion = TotpMultiFactorGenerator.assertionForEnrollment( totpSecret, verificationCode ); await multiFactor(currentUser).enroll(multiFactorAssertion, mfaDisplayName);
Вход пользователей с использованием второго фактора
Для авторизации пользователей с помощью TOTP MFA используйте следующий код:
Импортируйте необходимые классы и функции MFA:
import { getAuth, getMultiFactorResolver, TotpMultiFactorGenerator, } from "firebase/auth";
Вызовите один из методов
signInWith
, как если бы вы не использовали MFA. (Например,signInWithEmailAndPassword()
.) Если метод выдает ошибкуauth/multi-factor-auth-required
, запустите поток MFA вашего приложения.try { const userCredential = await signInWithEmailAndPassword( getAuth(), email, 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 (error) { switch (error.code) { case "auth/multi-factor-auth-required": // Initiate your second factor sign-in flow. (See next step.) // ... break; case ...: // Handle other errors, such as wrong passwords. break; } }
Процесс многофакторной аутентификации (MFA) вашего приложения должен сначала предложить пользователю выбрать второй фактор аутентификации. Список поддерживаемых вторых факторов можно получить, изучив свойство
hints
экземпляраMultiFactorResolver
:const mfaResolver = getMultiFactorResolver(getAuth(), error); const enrolledFactors = mfaResolver.hints.map(info => info.displayName);
Если пользователь выбирает использование TOTP, предложите ему ввести TOTP, отображаемый в приложении аутентификации, и использовать его для входа:
switch (mfaResolver.hints[selectedIndex].factorId) { case TotpMultiFactorGenerator.FACTOR_ID: const otpFromAuthenticator = // OTP typed by the user. const multiFactorAssertion = TotpMultiFactorGenerator.assertionForSignIn( mfaResolver.hints[selectedIndex].uid, otpFromAuthenticator ); try { const userCredential = await mfaResolver.resolveSignIn( multiFactorAssertion ); // Successfully signed in! } catch (error) { // Invalid or expired OTP. } break; case PhoneMultiFactorGenerator.FACTOR_ID: // Handle SMS second factor. break; default: // Unsupported second factor? break; }
Отписаться от TOTP MFA
В этом разделе описывается, как действовать в случае отмены регистрации пользователя в TOTP MFA.
Если пользователь подписался на несколько вариантов MFA и отменяет подписку на последний активированный вариант, он получает сообщение auth/user-token-expired
и выходит из системы. Пользователю необходимо снова войти в систему и подтвердить свои учётные данные, например, адрес электронной почты и пароль.
Чтобы отменить регистрацию пользователя, обработать ошибку и запустить повторную аутентификацию, используйте следующий код:
import {
EmailAuthProvider,
TotpMultiFactorGenerator,
getAuth,
multiFactor,
reauthenticateWithCredential,
} from "firebase/auth";
try {
// Unenroll from TOTP MFA.
await multiFactor(currentUser).unenroll(mfaEnrollmentId);
} catch (error) {
if (error.code === 'auth/user-token-expired') {
// If the user was signed out, re-authenticate them.
// For example, if they signed in with a password, prompt them to
// provide it again, then call `reauthenticateWithCredential()` as shown
// below.
const credential = EmailAuthProvider.credential(email, password);
await reauthenticateWithCredential(
currentUser,
credential
);
}
}
Что дальше?
- Управляйте многофакторными пользователями программно с помощью Admin SDK .