@kolomat

Как авторизоваться, если есть csrf-token?

Добрый день, подскажите по такому вопросу. Пытаюсь написать парсер для сбора остатков с сайта поставщика, но проблема стала в том что бы увидеть остаток надо авторизироваться.
Помимо логина и пароля там используется csrf-token, но проблема в том что он не сохраняется в сессии, он при каждом запросе генерируется новый. Есть такой код
$curl = curl_init();
curl_setopt($curl, CURLOPT_COOKIESESSION, true);
curl_setopt($curl, CURLOPT_COOKIEFILE, __DIR__  . '/cookie.txt');
curl_setopt($curl, CURLOPT_COOKIEJAR, __DIR__  . '/cookie.txt');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3');
curl_setopt($curl, CURLOPT_URL, '$url');
$html = curl_exec($curl);
preg_match('/<input type="hidden" name="_csrf" value="(.*)">/Uis',$html, $csrf);

$token = $csrf[1];

$data = [
	'_csrf' => $token,
	'LoginForm[username]' => 'login',
	'LoginForm[password]' => 'pass',
	'LoginForm[rememberMe]' => 1
	
];

$data = http_build_query($data);

curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
echo $html = curl_exec($curl);

Но проблема в том что сначала я получаю токен, а когда отправляю POST запрос он уже другой.
Может сталкивался кто-то с подобным и может подсказать решение?
  • Вопрос задан
  • 817 просмотров
Пригласить эксперта
Ответы на вопрос 1
Demisang
@Demisang
Backend PHP-developer
Сайт вашего партнёра написан на Yii2 framework.
Вот точное место кода(строка 1810), где производится валидация CSRF-токена: https://github.com/yiisoft/yii2/blob/master/framew...

Что там происходит:
1. Проверяется, если метод запроса GET HEAD или OPTIONS, то ничего не делать и токен не нужен.
2. Проверяется, совпадает ли CSRF-токен, который хранится в $_SESSION с тем, что пришёл вместе с запросом.

Чтобы не расписывать весь процесс дам простой ответ:
CSRF-токен обновляется после КАЖДОГО запроса(даже GET), поэтому просто: перед тем, как вы отправляете POST/PUT/DELETE запросы, запросите любую страницу сайта через GET, сохраните токен и используйте его для следующего запроса.

Эта защита сделана, чтобы нельзя было отправлять вредоносные запросы, например сделайте картинку <img src="http://example.com/logout"> и любой пользователь, который её увидит, будет разлогинен на сайте example.com
Ответ написан
Ваш ответ на вопрос

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

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