Как правильно отправить POST запрос с CSRF токеном для Laravel?

Добрый день. Пытаюсь отправить POST запрос на другой сайт, через cURL. Адрес https://promokod.pikabu.ru/coupon/5ka/Lty7boqhMLLy хочу получить ответ в котором есть json, оттуда вытащить ключ promocode.

Предполагаю, что требуется для начала получить CSRF token. Захожу на страницу и получаю этот токен, пытаюсь отправить, но в ответ получаю ошибку { "message": "CSRF token mismatch." }. Насколько я понимаю, данный сайт сделан на Laravel.

Делаю так:
<?php
// Инициализация cURL-сессии для GET-запроса страницы и извлечения CSRF-токена
$ch = curl_init();

// Установка параметров cURL-сессии для GET-запроса
curl_setopt($ch, CURLOPT_URL, 'https://promokod.pikabu.ru/shops/5ka');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');

// Выполнение GET-запроса
$response = curl_exec($ch);

// Закрытие cURL-сессии
curl_close($ch);

// Парсинг страницы для извлечения CSRF-токена
preg_match('/<meta name="csrf-token" content="(.+?)">/', $response, $matches);
if (isset($matches[1])) {
    $csrf_token = $matches[1];
} else {
    die("CSRF-токен не найден");
}

// Заголовки для POST-запроса
$headers = [
    "Accept: application/json, text/plain, */*",
    "Accept-Encoding: gzip, deflate, br",
    "Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
    "Connection: keep-alive",
    "Content-Length: 2",
    "Content-Type: application/json;charset=UTF-8",
    "Cookie: pcid=4yDnaZt3zv2; ...",
    "DNT: 1",
    "Host: promokod.pikabu.ru",
    "Origin: https://promokod.pikabu.ru",
    "Referer: https://promokod.pikabu.ru/shops/5ka",
    "Sec-Fetch-Dest: empty",
    "Sec-Fetch-Mode: cors",
    "Sec-Fetch-Site: same-origin",
    "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "X-Requested-With: XMLHttpRequest",
    "X-XSRF-TOKEN: " . $csrf_token
];

// Инициализация cURL-сессии для POST-запроса
$ch = curl_init();

// Установка параметров cURL-сессии для POST-запроса
curl_setopt($ch, CURLOPT_URL, 'https://promokod.pikabu.ru/coupon/5ka/Lty7boqhMLLy');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([])); // Данные запроса (пустой JSON в данном случае)

// Выполнение POST-запроса
$response = curl_exec($ch);

// Закрытие cURL-сессии
curl_close($ch);

// Обработка ответа от сервера
echo $response;
?>

Заголовки запроса, которые посылает браузер:
651f9784333eb781392808.png

Тот токен, что я вижу на странице, отличается от того, что посылается браузером. Отличается и размером и внешним видом, я так понимаю, он возможно генерируется как-то. Подскажите пожалуйста, как получить правильный ответ от сервера.
  • Вопрос задан
  • 743 просмотра
Пригласить эксперта
Ответы на вопрос 1
nokimaro
@nokimaro
Меня невозможно остановить, если я смогу начать.
csrf-token из html не используется
смотрите cookies которые присылает сервер при GET-запросе к https://promokod.pikabu.ru/shops/5ka
в заголовках приходит Set-Cookie: XSRF-TOKEN=
curl -L -I "https://promokod.pikabu.ru/shops/5ka"
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: no-cache, private
Date: Fri, 06 Oct 2023 12:56:29 GMT
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
Set-Cookie: XSRF-TOKEN=eyJpdiI6ImZuTllpTWRIb2ZDalF5.......TkyOWY3In0%3D; expires=Fri, 13-Oct-2023 12:56:29 GMT; Max-Age=604800; path=/


Это значение и надо использовать для дальнейшего POST-запроса
Ответ написан
Ваш ответ на вопрос

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

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