Перейти к основному содержимому

Типы MFA факторов

VoxKey поддерживает 5 типов MFA факторов через единый API. У каждого фактора одинаковый интерфейс challenge/verify -- разница в том, как пользователь предоставляет верификацию.

Сравнение

ФакторAPI значениеДоставкаДействие пользователяЛучше всего для
TOTPtotpНет (генерируется приложением)Ввести 6-значный код из приложения-аутентификатораНаиболее безопасный для повседневного использования
EmailemailКод отправлен на emailВвести 6-значный код из письмаПользователи без приложения-аутентификатора
SMSsmsКод отправлен по SMSВвести 6-значный код из SMSЗапасной вариант
WebAuthnwebauthnЗапрос браузераПрикосновение к сенсору / биометрия / ключ безопасностиНаивысшая безопасность, лучший UX
Backup Codebackup_codeНет (предварительно сгенерированы)Ввести 8-символьный кодЭкстренный доступ при недоступности основного фактора

Rate limits и TTL

ПараметрЗначение
TTL challenge5 минут
Макс. попыток верификации на challenge5
Rate limit создания challenge5 в минуту (на пользователя+клиент)
Rate limit верификации10 за 5 минут (на пользователя+IP)

TOTP

Использует приложения-аутентификаторы (Google Authenticator, Authy, 1Password и др.).

  • Без внешней доставки -- код генерируется на устройстве пользователя
  • Challenge создаёт запись, но ничего не отправляет
  • Коды действительны ~30 секунд с допуском ±1 окно для расхождения часов
  • Самый надёжный: работает офлайн, нет зависимости от провайдеров email/SMS
// Ответ challenge
{ "challenge_type": "code" }

// Запрос верификации
{ "code": "123456" }

Email

Одноразовый код, отправленный на зарегистрированный email пользователя.

  • Challenge отправляет 6-значный код через сервис уведомлений realm'а
  • Хэш кода хранится в challenge (не в сессии)
  • Создание нового email challenge инвалидирует предыдущий (семантика переотправки)
  • Ответ включает замаскированный email-адрес
// Ответ challenge
{
"challenge_type": "code",
"delivery": {
"destination": "t***@example.com",
"sent": true
}
}

SMS

Одноразовый код, отправленный по SMS на зарегистрированный телефон пользователя.

  • Тот же паттерн что у Email, но через SMS канал
  • Создание нового SMS challenge инвалидирует предыдущий
  • Ответ включает замаскированный номер телефона
// Ответ challenge
{
"challenge_type": "code",
"delivery": {
"destination": "+7***45",
"sent": true
}
}

WebAuthn / Passkey

Аппаратные ключи безопасности, сканеры отпечатков, Face ID, Windows Hello.

  • Challenge генерирует PublicKeyCredentialRequestOptions для WebAuthn API браузера
  • userVerification установлен в "required" для критичных действий
  • Ответ включает полный объект options для navigator.credentials.get()
  • Клиент отправляет assertion response обратно для верификации
// Ответ challenge
{
"challenge_type": "webauthn",
"webauthn_options": {
"challenge": "base64url...",
"allowCredentials": [...],
"userVerification": "required"
}
}

// Запрос верификации
{
"credential": {
"id": "base64url...",
"rawId": "base64url...",
"response": {
"authenticatorData": "base64url...",
"clientDataJSON": "base64url...",
"signature": "base64url..."
},
"type": "public-key"
}
}

WebAuthn flow на клиенте

// 1. Получаем challenge
const { challenge_id, webauthn_options } = await createChallenge('webauthn');

// 2. WebAuthn API браузера
const credential = await navigator.credentials.get({
publicKey: webauthn_options,
});

// 3. Отправляем assertion на верификацию
const result = await fetch(`/api/v1/{realm}/mfa/challenges/${challenge_id}/verify`, {
method: 'POST',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ credential }),
});

Backup Codes

Предварительно сгенерированные одноразовые коды для экстренного доступа.

  • 10 буквенно-цифровых кодов генерируются при регистрации
  • Каждый код можно использовать только один раз -- потребляется сразу после успешной верификации
  • Без внешней доставки -- пользователь должен заранее сохранить коды
  • Используйте когда основной фактор недоступен (потерян телефон, нет доступа к email)
// Запрос верификации
{ "code": "A3BGP2ZW" }
warning

Backup коды одноразовые. После верификации код потребляется навсегда. Рекомендуется напоминать пользователям о перегенерации кодов когда их запас заканчивается.