#php #laravel #http
Вопрос:
Мне нужно программно загрузить CSV-файл, который доступен только после того, как вы вошли на веб-сайт.
Когда я пытаюсь сделать это в Insomnia / Postman, это отлично работает, но я не могу понять, как это сделать в Laravel. Я подозреваю, что неправильно обрабатываю / использую файл cookie сеанса.
Это то, что я делаю при бессоннице / Почтальон:
- Я отправляю запрос на публикацию на страницу входа в систему веб-сайта вместе с именем пользователя и паролем в виде составных данных/данных формы.
- Я отправляю запрос на получение URL-адреса CSV-файла и получаю длинную строку CSV (тип содержимого: приложение/vnd.ms-excel)
Это ИМЕННО то, что мне нужно сделать в Laravel, но я просто не могу этого понять…
Это мой код:
public static function getCSVFeed()
{
$login = Http::withHeaders([
"Content-Type" => "multipart/form-data",
])->post(config("csvfeed_login_url"), [
"_username" => config("csvfeed_username"),
"_password" => config("csvfeed_password"),
]);
$sessionCookie = $login
->cookies()
->getCookieByName("PHPSESSID")
->toArray();
$sessionCookieName = $sessionCookie["Name"];
$sessionCookieValue = $sessionCookie["Value"];
$response = Http::withHeaders([
"Cookie" => $sessionCookieName . "=" . $sessionCookieValue,
])->get(config("csvfeed_url"));
return $response;
}
Когда я выполняю этот код, он возвращает не строку CSV, а HTML-код страницы 404 веб-сайта, что предполагает, что я не вошел в систему.
Редактировать:
Я провел еще несколько поисков и устранений неполадок. Я вошел в систему вручную в своем браузере, скопировал файл cookie «PHPSESSID» и жестко закодировал его в своем запросе GET, и я действительно получил ответ, содержащий CSV!
Это означает, что часть входа в мой код не работает, хотя я делаю то же самое, что и в Insomnia / Postman.
Когда я отправляюсь в Бессонницу и копирую свой запрос как Curl, я получаю следующее:
curl --request POST
--url **login URL**
--header 'Content-Type: multipart/form-data; boundary=---011000010111000001101001'
--form _username=**username**
--form '_password=**password**'
Единственное различие, которое я могу заметить,-это часть «граница=— — 011000010111000001101001», но я не знаю, что это такое и как это реализовать в PHP.
Комментарии:
1. Вы отправляете неправильный заголовок, касающийся файлов cookie.
Set-Cookie
это заголовок ответа , с помощью которого сервер отвечает, чтобы установить файл cookie. Заголовок запроса , который клиент использует для отправки этих файлов cookie обратно, таковCookie
. developer.mozilla.org/en-US/docs/Web/HTTP/…2. Большое вам спасибо за совет! Я изменил заголовок на
Cookie
, и теперь он действительно работает, когда я жестко кодирую файл cookie сеанса известного качества, поэтому я могу сделать вывод, что в части входа в мой код находится проблема. Я отредактировал свой вопрос с более подробной информацией.3. Вероятно
multipart/form-data
, для начала это не обязательно (на самом деле это для загрузки файлов), вероятно, подойдет «нормальный»application/x-www-form-urlencoded
. Попробуйте синтаксис laravel.com/docs/8.x/…4. @CBroe Вы были правы, сейчас все работает так, как ожидалось. Спасибо!
Ответ №1:
Кредит идет @CBroe
Оказывается, я неправильно вошел в систему. multipart/form-data
Заголовок не нужен. Вместо этого я должен был поставить префикс метода post asForm()
.
Это рабочий код:
public static function getCSVFeed(): array
{
$login = Http::asForm()->post(config("csvfeed.login_url"), [
"_username" => config("csvfeed.username"),
"_password" => config("csvfeed.password"),
]);
$sessionCookie = $login
->cookies()
->getCookieByName("PHPSESSID")
->toArray();
$sessionCookieName = $sessionCookie["Name"];
$sessionCookieValue = $sessionCookie["Value"];
$response = Http::withHeaders([
"Cookie" => $sessionCookieName . "=" . $sessionCookieValue,
])->get(config("csvfeed.url"));
return str_getcsv($response, PHP_EOL);
}