Интеграция официального виджета входа в Telegram позволяет пользователям аутентифицироваться в веб-приложении с помощью своей учетной записи Telegram. Когда пользователь авторизуется через виджет, Telegram передает параметры аутентификации (например, id, first_name, имя пользователя, Дата авторизации, и хэшей) обратно на указанный URL-адрес перенаправления или обратный вызов JavaScript.
В этом уроке мы построим механизм валидации бэкенда на PHP и реализуем его внутри контроллера приложений Yii2. Мы вычислим ожидаемую подпись HMAC-SHA-256, выполним безопасное по времени сравнение хешей, проверим свежесть подписи и свяжем входящие Телеграм ID в вашу базу данных пользователей.
Что охватывает это руководство: - Построение data_check_string в соответствии со спецификациями виджета входа в Telegram. - Генерация секретного ключа через sha256(bot_token). - Проверка подписей полезной нагрузки с помощью hash_equals(). - Привязка проверена Телеграм ID записи в Yii2.
Что делает это руководство not cover: - Настройка интерфейсных виджетов JavaScript или кода вставки HTML. - Приложение Telegram Mini initData верификация (которая использует другой процесс получения секретного ключа).
---
Алгоритм верификации Telegram
В отличие от Mini App initData (который использует буквенную строку "WebAppData" как ключ HMAC), стандартный виджет входа в Telegram получает свой секретный ключ, принимая двоичный хэш SHA-256 вашего токена бота.
Шаги алгоритма: 1. Извлеките хэшей параметр из входящей полезной нагрузки. 2. Отфильтровать хэшей от оставшихся клавиш. 3. Отсортируйте оставшиеся пары ключ-значение в алфавитном порядке по имени ключа. 4. Форматировать каждую пару как значение ключа и присоединяйтесь к ним с символами новой строки (\n). 5. Сгенерируйте секретный ключ: hash('sha256', $botToken, true). 6. Вычислить hash_hmac('sha256', $dataCheckString, $secretKey). 7. Проверьте вывод по полученному хешу, используя hash_equals(). 8. Убедитесь, что Дата авторизации находится в пределах приемлемого порога (например, 86 400 секунд).
Вот многоразовый класс обслуживания PHP, реализующий эту логику проверки:
<?php
declare(strict_types=1);
namespace app\components;
final class TelegramLoginValidator
{
public function isValid(array $authData, string $botToken, int $maxAgeSeconds = 86400): bool
{
if (!isset($authData['hash'], $authData['auth_date'])) {
return false;
}
$checkHash = (string)$authData['hash'];
unset($authData['hash']);
// Check payload freshness
$authDate = (int)$authData['auth_date'];
if ((time() - $authDate) > $maxAgeSeconds) {
return false;
}
// Filter non-string values and build key=value list
$dataCheckArr = [];
foreach ($authData as $key => $value) {
if (is_scalar($value)) {
$dataCheckArr[] = $key . '=' . $value;
}
}
// Sort keys alphabetically
sort($dataCheckArr, SORT_STRING);
$dataCheckString = implode("\n", $dataCheckArr);
// Secret key is the raw binary SHA-256 hash of the bot token
$secretKey = hash('sha256', $botToken, true);
$hash = hash_hmac('sha256', $dataCheckString, $secretKey);
return hash_equals($hash, $checkHash);
}
}
---
Интеграция с контроллером Yii2
Затем подключите этот валидатор к действию контроллера Yii2. Мы извлекаем маркер бота из переменных среды или Yii::$app->params, выполните проверку достоверности и либо свяжите входящие Телеграм ID существующей сессии аутентифицированного пользователя или создать новую учетную запись пользователя.
Убедитесь, что Пользователь таблица базы данных имеет индексированный Телеграм ID столбец (BIGINT, nullable, unique).
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\web\BadRequestHttpException;
use app\models\User;
use app\components\TelegramLoginValidator;
class AuthController extends Controller
{
public function actionTelegramCallback()
{
$requestParams = Yii::$app->request->get();
$botToken = (string)(getenv('TELEGRAM_BOT_TOKEN') ?: (Yii::$app->params['telegramBotToken'] ?? ''));
if (empty($botToken)) {
throw new \LogicException('Telegram bot token is not configured.');
}
$validator = new TelegramLoginValidator();
if (!$validator->isValid($requestParams, $botToken)) {
throw new BadRequestHttpException('Invalid or expired Telegram authentication signature.');
}
$telegramId = (int)$requestParams['id'];
$username = $requestParams['username'] ?? null;
// Check if a user with this telegram_id already exists
$user = User::findOne(['telegram_id' => $telegramId]);
if (!$user) {
// If currently logged in, link telegram_id to current profile
if (!Yii::$app->user->isGuest) {
/** @var User $user */
$user = Yii::$app->user->identity;
$user->telegram_id = $telegramId;
$user->save(false, ['telegram_id']);
Yii::$app->session->setFlash('success', 'Telegram account connected successfully.');
return $this->redirect(['/user/profile']);
}
// Register a new user account bound to this Telegram identity
$user = new User();
$user->telegram_id = $telegramId;
$user->username = $username ?: 'tg_' . $telegramId;
$user->generateAuthKey(); // Sets random auth_key for session security
if (!$user->save()) {
throw new \RuntimeException('Failed to register user account.');
}
}
// Log the user into the Yii2 application session
Yii::$app->user->login($user, 3600 * 24 * 30);
return $this->redirect(['/site/dashboard']);
}
}
---
V. СООБРАЖЕНИЯ, СВЯЗАННЫЕ С ПОДГОТОВКОЙ МАТЕРИАЛОВ
1. Конфигурация переменной среды: Никогда не вводите токены ботов в код. Храните TELEGRAM_BOT_TOKEN в переменных системной среды или безопасно загружены Защита экологии файлы с использованием getenv. 2. Защита от повтора 26 мая Дата авторизации проверка обеспечивает максимальное окно (например, 24 часа). Если ваше приложение обрабатывает транзакции с высокой стоимостью, подумайте о хранении использованных хэшей строки в Redis на время действия окна истечения срока действия, чтобы полностью предотвратить атаки повтора. 3. Логика привязки аккаунта: Если пользователь уже прошел аутентификацию с помощью традиционных учетных данных (адрес электронной почты/пароль), предложите ему связать свою учетную запись Telegram со страницы своего профиля, а не перезаписывать существующие записи автоматически.
Нужны пользовательские архитектуры ботов или специализированные бэкэнд-интеграции, созданные для производственных рабочих нагрузок? BotCreator — студия, которая поставляет Telegram-ботов /мини-приложения.