How to get past login screen on Guzzle call
Question
I have to send information to an external website using cURL. I set up Guzzle on my Laravel application. I have the basics set up, but according to the documentation of the website, there is an action that's required for the username and password. How can I pass the 'action' along with the credentials needed to log in and get access?
The website states:
curl [-k] –dump-header <header_file> -F “action=login” -F “username=<username>” -F “password=<password>” https://<website_URL>
My controller:
$client = new \GuzzleHttp\Client();
$response = $client->get('http://website.com/page/login/', array(
'auth' => array('username', 'password')
));
$xml = $response;
echo $xml;
The website will load on the echo
, but it will only pull up the login screen. I need those credentials to bypass the login screen (with a successful login) to get to the portion of information I need for cURL.
Solution
curl -F
submits a POST request instead of a GET request. So you'll need to modify your code accordingly, something like
$client = new \GuzzleHttp\Client();
$response = $client->post('http://website.com/page/login/', [
'body' => [
'username' => $username,
'password' => $password,
'action' => 'login'
],
'cookies' => true
]
);
$xml = $response;
echo $xml;
See http://guzzle.readthedocs.org/en/latest/quickstart.html#post-requests, http://curl.haxx.se/docs/manpage.html#-F
Edit:
Just add ['cookies' => true]
to requests in order to use the auth cookie associated with this GuzzleHttp\Client()
. http://guzzle.readthedocs.org/en/latest/clients.html#cookies
$response2 = $client->get('http://website.com/otherpage/', ['cookies' => true]);
OTHER TIPS
I was having trouble getting @JeremiahWinsley's answer to work on newer version of Guzzle so I've updated their code to work as of Guzzle 5.x.
Three major changes are required
- Using
form_params
instead ofbody
to prevent the error "Passing in the "body" request option as an array to send a POST request has been deprecated." - Changing the cookies to use the
CookieJar
object - Use
->getBody()->getContents()
to get the body of the request
Here is the updated code:
$client = new \GuzzleHttp\Client();
$cookieJar = new \GuzzleHttp\Cookie\CookieJar();
$response = $client->post('http://website.com/page/login/', [
'form_params' => [
'username' => $username,
'password' => $password,
'action' => 'login'
],
'cookies' => $cookieJar
]
);
$xml = $response->getBody()->getContents();
echo $xml;
And to continue using cookies in future requests, pass in the cookieJar
to the request:
$response2 = $client->get('http://website.com/otherpage/', ['cookies' => $cookieJar]);
I was having trouble getting @JeremiahWinsley's and @Samsquanch's answer to work on newer version of Guzzle. So I've updated the code to work as of Guzzle 6.x.
Guzzle 6.x. documents: http://docs.guzzlephp.org/en/stable/index.html
Here is the updated code:
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
try {
$client = new Client();
$cookieJar = new CookieJar();
$response = $client->request('POST', 'http://website.com/page/login/', [
'form_params' => [
'username' => 'test@example.com',
'password' => '123456'
],
'cookies' => $cookieJar
]);
$response2 = $client->request('GET', 'http://website.com/otherpage/', [
'cookies' => $cookieJar
]);
if ($response2->getStatusCode() == 200) {
return $response2->getBody()->getContents();
} else {
return "Oops!";
}
} catch (\Exception $exception) {
return 'Caught exception: ', $exception->getMessage();
}