Reputation: 11
I need to programmatically download a CSV file that is only available after you have logged in to a website.
When I try to accomplish this in Insomnia / Postman, it works perfectly, but I can't figure out how to accomplish this in Laravel. I suspect that I am not handling / utilizing my session cookie correctly.
This is what I do in Insomnia / Postman:
This is EXACTLY what I need to do in Laravel, but I just can't seem to figure it out...
This is my code:
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;
}
When I execute this code, it does not return a CSV string, but the HTML of the website's 404 page, which suggests that I am not logged in.
Edit:
I did some more troubleshooting. I logged in manually in my browser and copied the 'PHPSESSID' cookie and hardcoded it in my GET request and I actually got a response that contained CSV!
This means that the login part is of my code is failing, even though I am doing the exact same thing I did in Insomnia / Postman.
When I go to Insomnia and copy my request as Curl, I get the following:
curl --request POST \
--url **login URL** \
--header 'Content-Type: multipart/form-data; boundary=---011000010111000001101001' \
--form _username=**username** \
--form '_password=**password**'
The only difference I can spot is the "boundary=---011000010111000001101001" part, but I do not know what that is or how to implement that in PHP.
Upvotes: 0
Views: 1411
Reputation: 11
Credit goes to @CBroe
Turns out I was logging in incorrectly. The multipart/form-data
header is not needed. I should have prefixed the post method with asForm()
instead.
This is the working code:
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);
}
Upvotes: 1