Cómo pasar la pantalla de inicio de sesión en la llamada Guzzle
Pregunta
Tengo que enviar información a un sitio web externo usando cURL.Configuré Guzzle en mi aplicación Laravel.Tengo lo básico configurado, pero según la documentación del sitio web, se requiere una acción para el nombre de usuario y la contraseña.¿Cómo puedo pasar la 'acción' junto con las credenciales necesarias para iniciar sesión y obtener acceso?
El sitio web dice:
curl [-k] –dump-header <header_file> -F “action=login” -F “username=<username>” -F “password=<password>” https://<website_URL>
Mi controlador:
$client = new \GuzzleHttp\Client();
$response = $client->get('http://website.com/page/login/', array(
'auth' => array('username', 'password')
));
$xml = $response;
echo $xml;
El sitio web se cargará en el echo
, pero solo abrirá la pantalla de inicio de sesión.Necesito esas credenciales para omitir la pantalla de inicio de sesión (con un inicio de sesión exitoso) para acceder a la parte de información que necesito para cURL.
Solución
curl -F
envía una solicitud POST en lugar de una solicitud GET.Entonces necesitarás modificar tu código en consecuencia, algo como
$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;
Ver http://guzzle.readthedocs.org/en/latest/quickstart.html#post-requests, http://curl.haxx.se/docs/manpage.html#-F
Editar:
Solo agrega ['cookies' => true]
a solicitudes para utilizar la cookie de autenticación asociada con este GuzzleHttp\Client()
. http://guzzle.readthedocs.org/en/latest/clients.html#cookies
$response2 = $client->get('http://website.com/otherpage/', ['cookies' => true]);
Otros consejos
Estaba teniendo problemas para que la respuesta de @JeremiahWinsley funcionara en la versión más nueva de Guzzle, así que actualicé su código para que funcione a partir de Guzzle 5.x.
Se requieren tres cambios importantes
- Usando
form_params
en lugar debody
para evitar el error "Pasar la opción de solicitud" cuerpo "como una matriz para enviar una solicitud POST ha quedado obsoleto". - Cambiar las cookies para utilizar el
CookieJar
objeto - Usar
->getBody()->getContents()
para obtener el cuerpo de la solicitud
Aquí está el código actualizado:
$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;
Y para seguir usando cookies en futuras solicitudes, pase el cookieJar
a la solicitud:
$response2 = $client->get('http://website.com/otherpage/', ['cookies' => $cookieJar]);
Estaba teniendo problemas para que la respuesta de @JeremiahWinsley y @Samsquanch funcionara en la versión más nueva de Guzzle.Así que actualicé el código para que funcione a partir de Guzzle 6.x.
Engullir 6.x.documentos: http://docs.guzzlephp.org/en/stable/index.html
Aquí está el código actualizado:
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();
}