Проверка виджета входа в Telegram для аутентификации полезных нагрузок на PHP и Yii2

Интеграция официального виджета входа в 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-ботов /мини-приложения.

Новые статьи — в Telegram

Разбираем, что автоматизировать в бизнесе и как это работает на практике. Без спама.