Как на 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.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.