Разработка двухфакторной аутентификации (2FA) в мобильном приложении
2FA добавляет второй фактор после успешного ввода логина/пароля. Для финансовых приложений, корпоративных инструментов и любого сервиса с ценными данными — это не опциональная фича, а базовое требование безопасности. Вопрос не «нужна ли 2FA», а «какой метод подходит для аудитории».
Выбор метода 2FA
TOTP (Time-based One-Time Password) — пользователь сканирует QR-код в Google Authenticator, Microsoft Authenticator или любом TOTP-приложении. Каждые 30 секунд генерируется новый 6-значный код. Стандарт RFC 6238. Не требует интернета после настройки, работает без SMS, бесплатно. Лучший выбор для технически грамотной аудитории.
SMS OTP — код приходит по SMS при каждом входе. Знакомо массовой аудитории, но: может быть перехвачен (SIM swapping), зависит от покрытия, стоит деньги за каждую SMS. Для B2C приложений — часто единственный вариант, который пользователи воспринимают интуитивно.
Push-уведомление с подтверждением — при попытке входа пользователь получает push на доверенное устройство «Подтвердить вход?» с кнопками Да/Нет. Реализуется через FCM/APNs + backend. Хороший UX, но зависит от доставляемости push-уведомлений.
Email OTP — альтернатива SMS, аналогичная реализация, выше доставляемость, ниже ощущение срочности.
Реализация TOTP
На сервере при включении 2FA генерируем secret (20 байт случайных данных в Base32). Формируем otpauth://totp/AppName:[email protected]?secret=BASE32SECRET&issuer=AppName — это URI для QR-кода.
# Python — генерация secret и проверка кода
import pyotp
secret = pyotp.random_base32() # Сохраняем в БД, привязанный к пользователю
totp = pyotp.TOTP(secret)
# Проверка введённого кода
is_valid = totp.verify(user_input_code, valid_window=1)
# valid_window=1 допускает коды ±30 секунд от текущего — компенсация рассинхронизации часов
QR-код генерируем на сервере как PNG и отдаём клиенту через защищённый endpoint (только для авторизованного пользователя). Показываем один раз при настройке — повторно показывать QR небезопасно.
На мобильном клиенте — экран ввода 6-значного кода, аналогичный OTP-полю из SMS-авторизации. Автоматический submit при вводе 6-й цифры.
Резервные коды
При настройке TOTP — обязательно генерируем 8-10 одноразовых резервных кодов (recovery codes). Если пользователь потерял телефон с Authenticator — только они позволят войти в аккаунт. Показываем один раз, предлагаем сохранить. Храним как bcrypt-хэши.
Это критическая часть, которую часто откладывают. Без резервных кодов потерянный телефон = потеря доступа к аккаунту навсегда. Поддержка будет завалена запросами.
UX: когда требовать 2FA
Три стратегии:
При каждом входе — максимальная безопасность, минимальный UX. Оправдано для финансовых и корпоративных приложений.
Только на новом устройстве — доверенные устройства запоминаются через device_token, хранящийся в Keychain/Keystore. При входе с нового устройства или очистке данных — требуем 2FA. Лучший баланс для большинства приложений.
При рискованных операциях — step-up authentication: вход без 2FA, но при переводе денег/смене пароля — дополнительная проверка. Сложнее архитектурно, правильно для финтех.
Механизм доверенных устройств
// iOS — генерация device token после успешной 2FA
let deviceToken = UUID().uuidString
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "device_token",
kSecAttrService as String: "com.yourapp.auth",
kSecValueData as String: deviceToken.data(using: .utf8)!,
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
]
SecItemAdd(query as CFDictionary, nil)
На Android — EncryptedSharedPreferences с AndroidKeyStore-ключом для шифрования device token.
Device token передаётся при входе. Сервер проверяет: если токен есть и соответствует пользователю — 2FA не требуется. Срок жизни доверенного устройства: 30-90 дней, после — повторная 2FA.
Отключение и смена 2FA
Дать пользователю отключить 2FA нужно осторожно. Минимум: подтверждение действующим паролем + действующим 2FA кодом. Иначе злоумышленник, получивший доступ к сессии, может отключить защиту.
Смена TOTP-устройства: генерируем новый secret, старый показываем активным ещё 5 минут параллельно (migration window), потом инвалидируем.
Сроки: от 1,5 до 3 недель. TOTP с резервными кодами и доверенными устройствами — ближе к старшей границе. SMS 2FA без device trust — около недели.







