Как на PHP реализовать авторизацию пользователей через Telegram Login Widget (проверка подписи данных на сервере)?
Telegram Login Widget — официальный инструмент Telegram для авторизации пользователей на сторонних сайтах. После того как пользователь нажимает кнопку входа, Telegram передаёт на ваш сервер набор данных, подлинность которых необходимо проверить с помощью HMAC-SHA256.
## Шаг 1. Создание бота и получение токена
Перед началом создайте бота через @BotFather и получите токен вида `123456789:AAF…`. Этот токен используется для проверки подписи.
## Шаг 2. Подключение виджета на фронтенде
Добавьте на страницу следующий код:
html
После авторизации Telegram выполнит GET-запрос на `data-auth-url` с параметрами: `id`, `first_name`, `last_name`, `username`, `photo_url`, `auth_date`, `hash`.
## Шаг 3. Проверка подписи на PHP
Алгоритм проверки:
1. Убрать поле `hash` из полученных данных.
2. Отсортировать оставшиеся поля по алфавиту.
3. Сформировать строку вида `key=valuenkey=value`.
4. Вычислить секретный ключ: `SHA256(токен_бота)` — без HMAC, просто хэш.
5. Вычислить HMAC-SHA256 строки данных с использованием полученного ключа.
6. Сравнить результат с переданным `hash`.
php
«$k=$v»,
array_keys($data),
array_values($data)
));
// Секретный ключ — SHA256 от токена бота
$secretKey = hash(‘sha256’, $botToken, true);
// HMAC-SHA256
$calculatedHash = hash_hmac(‘sha256’, $dataCheckString, $secretKey);
// Проверяем время (не старше 86400 секунд)
if ((time() — (int)$data[‘auth_date’]) > 86400) {
return false;
}
return hash_equals($calculatedHash, $hash);
}
// Использование
$botToken = ‘ВАШ_ТОКЕН_БОТА’;
$telegramData = $_GET; // данные из GET-запроса
if (checkTelegramAuth($telegramData, $botToken)) {
$userId = (int)$telegramData[‘id’];
$firstName = htmlspecialchars($telegramData[‘first_name’]);
// Создаём сессию или находим пользователя в БД
$_SESSION[‘user_id’] = $userId;
$_SESSION[‘user_name’] = $firstName;
header(‘Location: /dashboard’);
} else {
http_response_code(403);
echo ‘Ошибка авторизации’;
}
## Шаг 4. Безопасность
— Всегда используйте `hash_equals()` для сравнения хэшей — это защищает от timing-атак.
— Проверяйте `auth_date`: данные не должны быть старше 24 часов.
— Храните токен бота в переменных окружения, а не в коде.
— Используйте HTTPS для защиты передаваемых данных.
— Не доверяйте данным без успешной проверки подписи.
## Итог
Такой подход позволяет безопасно идентифицировать пользователя Telegram без паролей, используя криптографическую подпись от серверов Telegram.
