BiometricManager — это API Telegram Mini Apps, через которое веб-приложение внутри Telegram может попросить устройство аутентифицировать пользователя по Face ID, Touch ID или Android-биометрии. Это закрывает огромный класс задач: вход в банковский кабинет, подтверждение платежа, разблокировка приватных фич — без пароля и без сервера сессий.
Разберём, как включить BiometricManager, как корректно запросить разрешение, как хранить биометрический токен и как сочетать с серверной аутентификацией.
Что умеет BiometricManager
Доступен с Bot API 7.2 (2024). Объект Telegram.WebApp.BiometricManager со свойствами:
isInited— инициализирован ли менеджер.isBiometricAvailable— поддерживает ли устройство биометрию.biometricType—"finger" | "face" | "unknown".isAccessRequested— спрашивали ли уже разрешение.isAccessGranted— дано ли разрешение.isBiometricTokenSaved— лежит ли токен в безопасном хранилище.deviceId— уникальный ID устройства (для серверной верификации).
И методы:
init(callback)— инициализация.requestAccess(params, callback)— попросить разрешение.authenticate(params, callback)— аутентифицировать.updateBiometricToken(token, callback)— сохранить/обновить токен.openSettings()— открыть настройки биометрии устройства.
Базовый сценарий
const bm = window.Telegram.WebApp.BiometricManager;
bm.init(() => {
if (!bm.isBiometricAvailable) {
showFallback("Биометрия не поддерживается, войдите паролем");
return;
}
if (!bm.isAccessGranted) {
bm.requestAccess(
{ reason: "Для быстрого входа в личный кабинет" },
(granted) => {
if (granted) loginWithBiometry();
}
);
} else {
loginWithBiometry();
}
});
function loginWithBiometry() {
bm.authenticate(
{ reason: "Подтвердите вход" },
(success, token) => {
if (success && token) {
api.loginWithBioToken(token).then((session) => {
/* успешный вход */
});
}
}
);
}
token — это произвольная строка, которую вы один раз сохранили через updateBiometricToken. Она не криптографически проверяема сама по себе, а служит ключом для серверной сессии.
Сохранение токена при первом входе
Логика:
- Юзер первый раз вошёл по паролю или OTP.
- Сервер выдал refresh-токен (long-lived, с device-binding).
- Mini App сохраняет refresh-токен через
updateBiometricToken. - На последующих заходах вызывает
authenticate→ получает токен → отдаёт серверу → сервер выдаёт access-токен.
async function onFirstLogin(refreshToken: string) {
await new Promise<void>((resolve, reject) =>
bm.updateBiometricToken(refreshToken, (ok) =>
ok ? resolve() : reject()
)
);
}
Длина токена ограничена 1024 символами. JWT с парой клеймов влезает с запасом.
Серверная верификация
bm.deviceId — уникальный ID устройства в контексте бота. Привязывайте refresh-токен к нему на бэкенде:
@router.post("/auth/biometric")
async def biometric_login(payload: BiometricPayload, request: Request):
token = payload.token
device_id = payload.device_id
user = await sessions.find_by_token_and_device(token, device_id)
if not user:
raise HTTPException(401, "invalid_token")
access = jwt.encode({"sub": user.id, "exp": now()+3600}, SECRET)
return {"access_token": access}
Если злоумышленник украл токен, но логинится с другого device_id — сервер отклоняет.
Fallback: что делать без биометрии
Не у всех есть Face ID, и не все хотят разрешать. Сценарии fallback:
| Ситуация | Что показать |
|---|---|
!isBiometricAvailable | Только пароль/OTP, биометрию не предлагаем |
!isAccessGranted после requestAccess | Кнопка «Включить позже в настройках» + пароль |
authenticate(success=false) | «Не получилось — войдите паролем» |
bm.openSettings() | Если юзер хочет включить заново |
Никогда не блокируйте вход полностью на биометрии — это поломает UX на десктопе.
Re-auth для критичных операций
Для перевода денег, смены пароля, удаления аккаунта — повторная биометрия даже в активной сессии:
async function confirmTransfer(amount: number) {
const ok = await new Promise<boolean>((res) =>
bm.authenticate(
{ reason: `Перевод ${amount} ₽` },
(success) => res(success)
)
);
if (!ok) return;
await api.confirmTransfer(amount);
}
Юзер видит нативный диалог Face ID с вашим reason — это и UX-понятно, и юридически фиксирует согласие.
Связь с initData
initData идентифицирует юзера в момент открытия Mini App. Биометрия — дополнительный фактор для критичных действий. Полная цепочка авторизации:
- Открытие Mini App →
initDataвалидируется на бэкенде → выдаётся access-токен (короткий, 5–15 мин). - Для платежей и приватных фич — biometric
authenticate→ подтверждение на сервере → выдаётся elevated-токен на 60 секунд. - Действие выполняется с elevated-токеном, который тут же сжигается.
Лимиты и нюансы
- Биометрия доступна только в нативных клиентах Telegram (iOS, Android, macOS Desktop). В вебе и Linux —
isBiometricAvailable = false. - Запрос разрешения можно делать только один раз — повторный
requestAccessпослеdeniedне покажет диалог; нуженopenSettings. - Токен сбрасывается, если юзер очистил данные Telegram, переустановил приложение или сменил биометрию устройства (новые отпечатки, перенастройка Face ID).
deviceIdстабилен в рамках устройства, но может смениться после переустановки Telegram.
Топ-5 ошибок
- Не вызывают
bm.init()перед использованием — все методы возвращают ошибку. - Сохраняют в
updateBiometricTokenaccess-токен (короткоживущий) — сессия отваливается через час. - Не привязывают токен к
deviceIdна бэкенде — токен переносится между устройствами. - Делают биометрию обязательной — юзеры на вебе не могут войти.
- Игнорируют
success=falseвauthenticate— баг в логе, фрустрация у юзера.
Итого
BiometricManager превращает Mini App в полноценное безопасное приложение: вход за полсекунды без паролей, повторная аутентификация на критичных действиях, серверная верификация по deviceId. Технически нужны 50 строк кода, серверный эндпоинт /auth/biometric и продуманный fallback. Это даёт +20–40% конверсии в активных юзеров, потому что барьер «введите пароль» больше не возникает каждый день.
Частые вопросы
Что произойдёт, если юзер сменит Face ID на iPhone?
Telegram аннулирует сохранённый биометрический токен — следующий authenticate вернёт success=false, и isBiometricTokenSaved станет false. Это защита от ситуации, когда злоумышленник зарегистрировал свой отпечаток в чужом устройстве. Mini App должен предложить заново войти по паролю и сохранить новый токен.
Биометрия работает на десктопе?
В Telegram Desktop для macOS — да, через Touch ID. На Windows — пока нет (на момент 2026 года Windows Hello не интегрирован). На Linux — нет. Для веб-клиентов (web.telegram.org) — нет. Mini App должен корректно проверять isBiometricAvailable и предлагать пароль на платформах без поддержки.
Можно ли узнать, что биометрия не прошла из-за неверного пальца?
Нет, authenticate отдаёт только success: boolean. Конкретная причина (отпечаток не распознан, юзер отменил, биометрия заблокирована после 5 неудач) скрыта внутри ОС. Для UX это нормально: показываете «Не получилось, попробуйте ещё раз или войдите паролем».
Как часто запрашивать биометрию?
Для входа — один раз в N дней (обычно 7–30). Для критичных операций (платёж, смена пароля) — каждый раз. Внутри сессии не дёргайте на каждый клик — это утомляет. Хорошее правило: биометрия = «согласие на действие», access-токен = «активная сессия».
Что хранить в биометрическом токене?
Refresh-токен с длительным TTL (90+ дней), привязанный на сервере к device_id и user_id. JWT с минимальными клеймами или просто случайная 256-битная строка-ключ к серверной сессии. Никогда не кладите туда персональные данные — токен может попасть в логи устройства при отладке.
Можно ли использовать биометрию для подписи платежа в Stars?
Технически да: вызываете authenticate перед sendInvoice, и только при успехе показываете invoice. Юридически это даёт дополнительный уровень неоспоримости транзакции — пользователь физически подтвердил намерение биометрией. Полезно для крупных сумм (от 5000 ₽).
Что делать, если юзер отказал в доступе к биометрии?
requestAccess нельзя показать второй раз — диалог системный и помнит ответ. Покажите кнопку «Включить биометрию в настройках» с вызовом bm.openSettings() — она открывает соответствующий раздел Telegram, где юзер может изменить решение. И всегда оставляйте альтернативу — пароль или OTP.