Telegram Mini App: почему нельзя авторизовывать пользователя по initDataUnsafe

Mini App открылась внутри Telegram, интерфейс получил имя и ID пользователя. Возникает соблазн отправить этот ID на сервер и сразу выдать доступ. Но данные, приходящие от браузера, не становятся достоверными только из-за того, что экран выглядит как Telegram. Если сервер доверяет произвольно переданному ID, чужой аккаунт можно ошибочно принять за свой.
Что Telegram передаёт приложению
Веб-приложение получает initData — исходные данные запуска — и удобное представление initDataUnsafe. Второе предназначено для использования в интерфейсе, но его нельзя считать доказательством личности без проверки. Для авторизации сервер должен проверить подлинность исходных данных по актуальной документации Telegram.
Сейчас документация описывает проверку с использованием токена бота и отдельную возможность проверки подписи третьей стороной. Это разные схемы. Не смешивайте их шаги и не копируйте старый пример из сообщения на форуме без сверки. Токен бота остаётся на сервере и не попадает в JavaScript страницы.
Граница доверия в одной таблице
| Значение | До серверной проверки | После успешной проверки |
|---|---|---|
| Имя и аватар | Только неподтверждённое оформление интерфейса | Профиль в пределах проверенного контекста |
| ID пользователя | Не основание для доступа | Ключ сопоставления с локальной учётной записью |
| auth_date | Может быть подменён вместе с остальными данными | Основание для проверки актуальности запуска |
| Произвольный start_param | Недоверенный вход | Всё ещё требует проверки бизнес-правил |
| Выбранный номер заказа | Недоверенный вход | Отдельная проверка принадлежности заказа обязательна |
Проверить подпись недостаточно для всех прав
Корректные данные запуска подтверждают происхождение соответствующего контекста, но не дают пользователю доступ к любому объекту вашей базы. После сопоставления аккаунта сервер проверяет роль, организацию и разрешённые действия. ID заказа из параметра запуска не должен обходить эту проверку.
Также проверьте актуальность по auth_date. Допустимый возраст задаётся политикой приложения, а не универсальным числом для всех Mini App. Учитывайте небольшую допустимую рассинхронизацию часов. Слишком старые данные или метка далеко в будущем требуют отклонения либо повторного запуска. Само поле времени имеет смысл только после проверки подлинности набора.
После входа — собственная управляемая сессия
Обычно проверенный запуск обменивают на сессию приложения с понятным сроком и механизмом завершения. Не передавайте один и тот же набор запуска бесконтрольно во все внутренние запросы как бессрочный пароль. Выбор способа хранения сессии зависит от архитектуры, защиты от XSS и CSRF и поддерживаемого контекста открытия.
В журналах не сохраняйте полный initData и токен бота. Для диагностики нужны результат проверки, причина отказа, технический ID запроса и безопасно выбранные признаки. Доступ к таким журналам ограничивают. Ошибка авторизации не должна раскрывать пользователю внутренние секреты проверки.
Что передать на приёмку
- Корректный свежий запуск принимается сервером.
- Изменение одного поля без корректной проверки отклоняется.
- Старые и недопустимо будущие данные не превращаются в действующую сессию.
- Прямой запрос с чужим ID пользователя без проверенного контекста не авторизует.
- Проверенный пользователь не получает заказ другой компании по подменённому параметру.
Проверки выполняются в собственном тестовом приложении. Для изучения политики времени не нужны действительные токены или чужие данные запуска. Инструмент ниже оценивает только возраст числовой метки относительно указанного серверного времени. Он намеренно не объявляет данные подлинными: подпись здесь не проверяется.
Если команда показывает лишь успешный вход из Telegram, этого недостаточно. Попросите продемонстрировать отказ при изменённом ID, истёкшем контексте и доступе к чужому объекту. Эти три проверки закрывают разные классы ошибок и должны оставаться в регрессии после обновления авторизации.
Проверка политики возраста auth_date без секретов
Подлинность initData НЕ проверяется. Не вставляйте токены, подписи или реальные данные запуска. Расчёт выполняется на вашем устройстве, введённые данные никуда не отправляются.
Материалы для проверки
Если нужна реализация
Состав работ зависит от текущего проекта и подтверждённой причины. Можно обсудить диагностику или разработку подходящего решения.
