web-dev-qa-db-fra.com

Garder la session en vie avec Curl et PHP

J'essaie de me connecter à une API, d'authentifier un utilisateur, puis d'afficher les détails de l'utilisateur. Ceci est accompli en accédant d'abord au noeud final de connexion à

http://api.example.com/login/<username>/<password>

pour vous connecter et ensuite pour voir les détails de l'utilisateur:

http://api.example.com/user/

Tout cela fonctionne dans un navigateur Web. Cependant, une fois que j'essaie d'utiliser Curl, la connexion fonctionne correctement, mais lorsque j'essaie d'afficher les détails de l'utilisateur, je récupère une erreur non autorisée 401. Je pense que c’est parce que Curl n’enregistre pas correctement les cookies de session? Quelqu'un peut-il expliquer pourquoi cela ne fonctionne pas et comment le réparer? J'ai essayé de chercher l'échange de pile, cependant, aucune des solutions que j'ai essayées n'a fonctionné pour ma situation. Le code que j'utilise pour boucler les points d'extrémité est présenté ci-dessous. Merci!

define("COOKIE_FILE", "cookie.txt");

// Login the user
$ch = curl_init('http://api.example.com/login/joe/smith');
curl_setopt ($ch, CURLOPT_COOKIEJAR, COOKIE_FILE); 
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
echo curl_exec ($ch);

// Read the session saved in the cookie file
echo "<br/><br/>";
$file = fopen("cookie.txt", 'r');
echo fread($file, 100000000);   
echo "<br/><br/>";

// Get the users details
$ch = curl_init('http://api.example.com/user');
curl_setopt ($ch, CURLOPT_COOKIEJAR, COOKIE_FILE); 
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
echo curl_exec ($ch);

Ce code produira:

HTTP/1.1 200 OK Date: Mon, 22 Oct 2012 21:23:57 GMT Server: LiteSpeed Connection: close X-Powered-By: PHP/5.3.14 Set-Cookie: cfapi=f481129c9616b8f69cc36afe16466545; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Type: application/json X-Powered-By: CFWAPI 0.1a Content-Length: 46 {"status":200,"msg":"Successfully Logged In."}

# Netscape HTTP Cookie File # http://curl.haxx.se/rfc/cookie_spec.html # This file was generated by libcurl! Edit at your own risk. api.example.com FALSE   /   FALSE   0   cfapi 94f63b07ccf7e34358c1c922341c020f 

HTTP/1.1 401 Unauthorized Date: Mon, 22 Oct 2012 21:23:57 GMT Server: LiteSpeed Connection: close X-Powered-By: PHP/5.3.14 Set-Cookie: cfapi=a8eb015a7c423dde95aa01579c4729a4; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Type: application/json X-Powered-By: CFWAPI 0.1a Content-Length: 49 {"status":401, "msg":"You need to login first!"}
51
John

Vous devez également définir l'option CURLOPT_COOKIEFILE.

Le manuel décrit ceci comme

Le nom du fichier contenant les données du cookie. Le fichier de cookie peut être au format Netscape ou simplement en-têtes de style HTTP vidés dans un fichier. Si le nom est une chaîne vide, aucun cookie n'est chargé, mais la gestion des cookies est toujours activée.

Puisque vous utilisez le cookie jar, vous enregistrez les cookies à la fin des demandes, mais depuis le CURLOPT_COOKIEFILE n'est pas indiqué, cURL n'envoie aucun des cookies enregistrés lors de demandes ultérieures.

34
drew010

Vous avez correctement utilisé "CURLOPT_COOKIEJAR" (écriture), mais vous devez également définir "CURLOPT_COOKIEFILE" (lecture).

curl_setopt ($ch, CURLOPT_COOKIEJAR, COOKIE_FILE); 
curl_setopt ($ch, CURLOPT_COOKIEFILE, COOKIE_FILE); 
28
Scuzzy

Voici comment vous faites CURL avec des sessions

//initial request with login data

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/login.php');
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/32.0.1700.107 Chrome/32.0.1700.107 Safari/537.36');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=XXXXX&password=XXXXX");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie-name');  //could be empty, but cause problems on some hosts
curl_setopt($ch, CURLOPT_COOKIEFILE, '/var/www/ip4.x/file/tmp');  //could be empty, but cause problems on some hosts
$answer = curl_exec($ch);
if (curl_error($ch)) {
    echo curl_error($ch);
}

//another request preserving the session

curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/profile');
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, "");
$answer = curl_exec($ch);
if (curl_error($ch)) {
    echo curl_error($ch);
}

J'ai vu ça sur ImpressPages

18
raveren

Yup, souvent appelé un "cookie jar", Google devrait en donner de nombreux exemples:

http://devzone.zend.com/16/php-101-part-10-a-session-in-the-cookie-jar/

http://curl.haxx.se/libcurl/php/examples/cookiejar.html <- bon exemple à mon humble avis

Copier ce dernier ici pour qu'il ne s'en aille pas ...

Connectez-vous à une page puis obtenez une autre page en transmettant tous les cookies de la première page. Written by Mitchell

<?php
/*
This script is an example of using curl in php to log into on one page and 
then get another page passing all cookies from the first page along with you.
If this script was a bit more advanced it might trick the server into 
thinking its netscape and even pass a fake referer, yo look like it surfed 
from a local page.
*/

$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, "/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_URL,"http://www.myterminal.com/checkpwd.asp");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "UserID=username&password=passwd");

ob_start();      // prevent any output
curl_exec ($ch); // execute the curl command
ob_end_clean();  // stop preventing output

curl_close ($ch);
unset($ch);

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_URL,"http://www.myterminal.com/list.asp");

$buf2 = curl_exec ($ch);

curl_close ($ch);

echo "<PRE>".htmlentities($buf2);
?>  
12
ficuscr