Разработка авторизации через Telegram Login
Telegram Login — нестандартный OAuth. У Telegram нет OIDC-совместимого провайдера, нет привычного Authorization Code Flow. Вместо этого — собственный виджет/протокол с криптографической верификацией через HMAC-SHA256. Это требует аккуратной реализации на стороне сервера и нескольких вариантов на клиенте в зависимости от задачи.
Два варианта Telegram Login для мобильных приложений
Telegram Login Widget — JavaScript-виджет для веба, который открывается в WebView внутри приложения. Пользователь нажимает «Войти через Telegram», появляется popup или QR, пользователь подтверждает в Telegram-приложении. Callback приходит в WebView с данными пользователя. Простейший вариант, минимум кода.
Telegram Bot + Deep Link — более нативный подход для мобильных. Бот генерирует одноразовую ссылку tg://resolve?domain=YOUR_BOT&start=AUTH_TOKEN. Приложение открывает эту ссылку — система открывает Telegram с чатом бота. Пользователь нажимает Start, бот получает сообщение /start AUTH_TOKEN через Webhook, верифицирует токен, вызывает ваш API. Приложение ждёт callback через WebSocket или polling.
Второй вариант сложнее архитектурно, но даёт полностью нативный UX: Telegram открывается как обычное приложение через Universal Link, не WebView.
Криптографическая верификация данных
Это самая важная часть Telegram Login. Данные, которые Telegram отдаёт клиенту (id, username, first_name, hash, auth_date), нужно верифицировать на сервере — иначе злоумышленник может подделать авторизацию.
Алгоритм верификации:
# Python (серверная сторона)
import hashlib
import hmac
def verify_telegram_auth(bot_token: str, auth_data: dict) -> bool:
check_hash = auth_data.pop('hash')
# Строка для верификации: отсортированные пары key=value через \n
data_check_string = '\n'.join(
f'{k}={v}' for k, v in sorted(auth_data.items())
)
# Секрет — SHA256 от bot token (не сам токен)
secret_key = hashlib.sha256(bot_token.encode()).digest()
# HMAC-SHA256
calculated_hash = hmac.new(
secret_key,
data_check_string.encode(),
hashlib.sha256
).hexdigest()
# Проверяем хэш и свежесть данных (не старше 24 часов)
return (calculated_hash == check_hash and
time.time() - int(auth_data['auth_date']) < 86400)
bot_token должен быть только на сервере — никогда в мобильном клиенте. Клиент передаёт весь набор данных от Telegram на backend, backend верифицирует.
Реализация WebView варианта
На мобильном клиенте проще всего: загружаем HTML-страницу с Telegram Login Widget в WKWebView (iOS) / WebView (Android). Страница сообщает результат через window.postMessage или URL redirect на custom scheme.
// iOS — обработка redirect из WebView
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url,
url.scheme == "myapp",
url.host == "telegram-callback" {
// Парсим query params — данные от Telegram
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
let params = components?.queryItems?.reduce([String:String]()) { ... }
handleTelegramAuth(params)
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
Ограничения и edge cases
Telegram Login требует привязки к домену: при создании виджета или настройке бота указываем домен, с которого разрешена авторизация. Для мобильного приложения без веб-версии это искусственное ограничение — нужно зарегистрировать любой подконтрольный домен и разместить на нём промежуточную страницу.
Пользователь без Telegram на устройстве: при открытии tg:// ссылки — ничего не происходит. Нужен fallback: предложить скачать Telegram или переключиться на другой метод входа.
Аккаунт Telegram не всегда имеет username (он необязателен). first_name — есть всегда. Email — Telegram никогда не передаёт.
Сроки: от 1 до 2 недель. WebView вариант — ближе к неделе. Нативный Deep Link через бота — до двух недель с учётом серверной части (Webhook, WebSocket для callback).







