Розробка двофакторної аутентифікації (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 — близько тижня.







