Задать вопрос
@sergise

Как сделать валидацию на Telegram Mini App?

У меня есть страница с джаваскриптом:

Код
document.addEventListener('DOMContentLoaded', () => {
            const tg = window.Telegram.WebApp;

            if (tg.initDataUnsafe) {
                const params = {
                    user: {
                        id: tg.initDataUnsafe.user.id,
                        first_name: tg.initDataUnsafe.user.first_name,
                        last_name: tg.initDataUnsafe.user.last_name,
                        username: tg.initDataUnsafe.user.username,
                        language_code: tg.initDataUnsafe.user.language_code
                    },
                    hash: tg.initDataUnsafe.hash,
                    auth_date: tg.initDataUnsafe.auth_date
                };

                // Логирование для отладки
                console.log('Params to send:', params);

                fetch('validate.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(params)
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        window.location.href = 'index.html';
                    } else {
                        document.querySelector('.loading-container').innerHTML = `
                            <h1>Ошибка</h1>
                            <p>${data.error}</p>
                        `;
                    }
                })
                .catch(error => {
                    document.querySelector('.loading-container').innerHTML = `
                        <h1>Ошибка</h1>
                        <p>Произошла ошибка при проверке данных</p>
                    `;
                });
            } else {
                document.querySelector('.loading-container').innerHTML = `
                    <h1>Ошибка</h1>
                    <p>Не удалось получить данные Telegram</p>
                `;
            }
        });

то-есть я отправляю post запрос с данными из Telegram WebApp.

Мой обработчик validate.php выглядит так:
Код

<?php
session_start();

function validate_telegram_data($data, $secret) {
    $check_hash = $data['hash'];
    unset($data['hash']);
    ksort($data);
    $data_check_string = explode('&', rawurldecode($check_hash));
    foreach ($data as $key => $value) {
        $data_check_string .= $key . '=' . $value . "\n";
    }
    

    $secret_key = hash_hmac('sha256', $telegram_bot_token, "WebAppData");
    $hash = hash_hmac('sha256', $data_check_string, $secret_key);

    $log_file = 'logs.txt';
    error_log('Data Check String: ' . $data_check_string . PHP_EOL, 3, $log_file);
    error_log('Secret Key: ' . $secret_key . PHP_EOL, 3, $log_file);
    error_log('Computed Hash: ' . $hash . PHP_EOL, 3, $log_file);
    error_log('Received Hash: ' . $check_hash . PHP_EOL, 3, $log_file);

    return hash_equals($hash, $check_hash);
}

$data = json_decode(file_get_contents('php://input'), true);

if (isset($data['user']['id']) && isset($data['hash'])) {
    $telegramid = $data['user']['id'];
    $hash = $data['hash'];

    $data_to_validate = [
        'auth_date' => $data['auth_date'],
        'first_name' => $data['user']['first_name'],
        'id' => $telegramid,
        'last_name' => $data['user']['last_name'],
        'username' => $data['user']['username'],
        'language_code' => $data['user']['language_code'],
        'hash' => $hash
    ];

    $telegram_bot_token = 'токен';

    if (validate_telegram_data($data_to_validate, $telegram_bot_token)) {
        $_SESSION['telegramid'] = $telegramid;
        echo json_encode(['success' => true]);
    } else {
        echo json_encode(['success' => false, 'error' => 'Invalid data']);
    }
} else {
    echo json_encode(['success' => false, 'error' => 'Missing parameters']);
}
?>



у меня не выходит сделать правильно валидацию по hash.
Лог

Data Check String: Arrayauth_date=1722074167
first_name=ИМЯ
id=АЙДИ
language_code=ru
last_name=
username=ЛОГИН

Secret Key: e2a4475b5210ac656bdce26ced5775a0bc48bd89a36a2cfbcb16f32a938adee1
Computed Hash: 0496cae44f6f6332a96963d1eb21f6d524ac3fc53a8643fc584918f20bca0f81
Received Hash: 99ef03e32a0a5090e2563f22527635bd2f54cbb870105e32e18526318dfdc8cb

как исправить проблему с проверкой хэша?
  • Вопрос задан
  • 633 просмотра
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
@ilachev
function validate_telegram_data($data, $secret) {
    $check_hash = $data['hash'];
    unset($data['hash']);
    ksort($data);
    
    // Формируем строку для проверки
    $data_check_string = '';
    foreach ($data as $key => $value) {
        $data_check_string .= $key . '=' . $value . '&';
    }
    $data_check_string = rtrim($data_check_string, '&'); // Удаляем последний '&'

    // Вычисляем секретный ключ
    $secret_key = hash_hmac('sha256', $secret, "WebAppData");
    // Вычисляем хэш
    $hash = hash_hmac('sha256', $data_check_string, $secret_key);

    $log_file = 'logs.txt';
    error_log('Data Check String: ' . $data_check_string . PHP_EOL, 3, $log_file);
    error_log('Secret Key: ' . $secret_key . PHP_EOL, 3, $log_file);
    error_log('Computed Hash: ' . $hash . PHP_EOL, 3, $log_file);
    error_log('Received Hash: ' . $check_hash . PHP_EOL, 3, $log_file);

    // Сравнение вычисленного хэша с полученным
    return hash_equals($hash, $check_hash);
}


попробуй так
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы