По документации телеграм: https://core.telegram.org/bots/webapps#validating-...
Получится вот такой код (PHP):
$bot_token = ‘ТОКЕН_БОТА'; $data = urldecode($_POST['data']); $hash = $_POST['hash']; $data = explode("&", $data); $new_data = array(); foreach($data as $value) { $value_array = explode("=", $value); if($value_array[0] == 'hash') {continue;} $new_data += array($value_array[0] => $value_array[1]); } ksort($new_data); $array_data = array(); foreach($new_data as $k => $v) { array_push($array_data, "$k=$v"); } $array_data = implode('n', $array_data); $secret_key = hash_hmac('sha256', $bot_token, "WebAppData"); if(hash_hmac('sha256', $array_data, $secret_key) == $hash) { echo 'ok!'; } else { echo ‘error'; } |
$bot_token = ‘ТОКЕН_БОТА'; $data = urldecode($_POST['data']); $hash = $_POST['hash']; $data = explode("&", $data); $new_data = array(); foreach($data as $value) { $value_array = explode("=", $value); if($value_array[0] == 'hash') {continue;} $new_data += array($value_array[0] => $value_array[1]); } ksort($new_data); $array_data = array(); foreach($new_data as $k => $v) { array_push($array_data, "$k=$v"); } $array_data = implode('n', $array_data); $secret_key = hash_hmac('sha256', $bot_token, "WebAppData"); if(hash_hmac('sha256', $array_data, $secret_key) == $hash) { echo 'ok!'; } else { echo ‘error'; }
Запрос из приложения:
$.post( "check", {"data":window.Telegram.WebApp.initData, "hash": window.Telegram.WebApp.initDataUnsafe.hash}, function( data ) { alert(data); }); |
$.post( "check", {"data":window.Telegram.WebApp.initData, "hash": window.Telegram.WebApp.initDataUnsafe.hash}, function( data ) { alert(data); });
Хеши при проверке не совпадают. Что не учтено при проверке подписи?
Дополнительно:
Не вникал, но код галимый, его бы упростить до строк 3-4. Начать хотя бы с этого: https://www.php.net/manual/ru/function.parse-str.php
psiklop, данные корректно обрабатываются для составления хеша, проверял всё. Скорее всего, после упрощения кода ничего не поменяется. Думаю, что проблема где-то на этапе создания и проверки хеша, но не могу понять, где именно
Дмитрий Нестеров, это не связано. Хорошо писать никто не отменял. В коде творится какая-то дичь, вертится по кругу без причины. Вообще есть опыт, после рефакторинга находятся еще и случайные ошибки.
psiklop, за замечание спасибо, код мне тоже хотелось подкорректировать, но после того, как сравнение ключей заработает, здесь это главное. $array_data формируется как нужно
Дмитрий Нестеров, не понял с каким хеш сравнивать надо, их два приходит: $_POST['hash'] и $_POST['data']['hash']. И также не понял тут: $array_data = implode('n', $array_data); если нужен перевод строки тогда нужны двойные кавычки, насколько я знаю.
psiklop, 1) эти хеши одинаковые, в документации тг написано 2) также как в документации тг написано, соединить параметры через n, и пример строки приведён, но с двойными кавычками также не работает, проверял
Дмитрий Нестеров, ну тем не менее для опытов и размышлений тебе:
echo md5("testn"); echo md5('testn'); |
echo md5("testn"); echo md5('testn');
Для проверки подписи мини-приложения в телеграм на сервере, вам следует выполнить следующие шаги:
1. Получить данные, переданные от телеграм в ваш сервер после запроса от пользователя. Обычно это JSON объект с информацией о запросе.
2. Извлечь из полученных данных подпись и само сообщение, которое было подписано.
3. Получить ваш секретный ключ, который был использован для подписи сообщения.
4. Вычислить хеш сообщения с использованием HMAC алгоритма с использованием вашего секретного ключа.
5. Сравнить вычисленный хеш с полученной подписью. Если они совпадают, значит подпись верна.
Пример кода на PHP для проверки подписи:
Не забудьте заменить `$your_secret_key` на ваш секретный ключ, который был использован для подписи сообщения. Таким образом, вы сможете проверить подпись мини-приложения в телеграм на вашем сервере.