Тестирование биометрии: Face ID, Touch ID, fingerprint
Биометрия выглядит просто: приложил палец / посмотрел на камеру → вошёл. На практике UX содержит десятки граничных случаев, и каждый сломанный — это юзер, заблокированный из приложения.
Базовая логика
iOS — LocalAuthentication.framework. Android — BiometricPrompt API (Android 6+).
Оба возвращают:
- Success — биометрия распознана.
- Cancel — юзер закрыл prompt.
- Fallback — выбрал ввести пароль.
- LockedOut — слишком много неудачных попыток.
- NotEnrolled — биометрия в системе не настроена.
Сценарии для тестирования
— Первый запуск: юзер логинится паролем → приложение предлагает включить биометрию → юзер соглашается → следующий раз входит по биометрии.
— Биометрия выключена в системе: предложение не показываем, обычный flow паролем.
— Биометрия удалена/переустановлена: на iOS если юзер удалил Face ID и настроил заново — keychain item остаётся, но LAPolicy.deviceOwnerAuthenticationWithBiometrics фейлится с ошибкой biometryChanged. Должны попросить пароль заново. Часто пропускают — приложение даёт зайти, что является дырой в безопасности.
— Lockout: 5 неудачных попыток на iOS → biometric заблокирован до разблокировки паролем устройства. Приложение должно показать понятный fallback.
— Камера занята: Face ID не работает если камера используется другим приложением. Редкий, но воспроизводимый кейс через FaceTime.
— Маска: Face ID на старых iPhone не работает в маске. Face ID with Mask (iPhone 12+) — работает, но требует отдельной настройки.
— Темнота: Face ID нужен свет. В полной темноте — не работает.
Безопасность
✅ При смене биометрии должен сбрасываться доступ. Юзер настроил Face ID жены — не должен иметь возможность войти в твой банк-приложение. Reproduce: добавь альтернативный Face ID в Settings → попробуй войти → должно отказать.
✅ Биометрия не сохраняет пароль на сервер. Биометрия — это только локальная проверка. Приложение должно хранить токен в Keychain/Keystore с привязкой к биометрии. При несовпадении — токен недоступен.
✅ Root/Jailbreak detection. На рутованном устройстве биометрия теоретически обходится. Сильные приложения (банки) отключают биометрию на jailbroken устройствах.
iOS-специфика
— LAContext.canEvaluatePolicy — проверка перед запросом. Возвращает enum LABiometryType.faceID, .touchID, .opticID (Vision Pro), .none.
— evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics) — только биометрия.
— evaluatePolicy(.deviceOwnerAuthentication) — биометрия с fallback на passcode.
Android-специфика
— BiometricManager.canAuthenticate(BIOMETRIC_STRONG) — нужен сильный биометр (соответствует Android Compatibility Definition).
— BIOMETRIC_WEAK — слабее, не подходит для chrome-уровня безопасности (банки).
— DEVICE_CREDENTIAL — fallback на PIN/паттерн.
Чек-лист регрессии
✅ Включил → выключил → включил → работает. ✅ Включил Face ID → удалил Face ID из Settings → попытка входа в приложение → попрос пароля. ✅ 5 неудачных попыток → lockout → fallback на пароль работает. ✅ Темнота → понятная ошибка, не «попробуйте ещё раз» бесконечно. ✅ Symulация: новый юзер устройства добавил свой Face ID → не имеет доступа.
Подробнее: Apple LocalAuthentication, Android Biometric login.