使用 Curl 和 PHP 保持会话活跃
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13020404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Keeping session alive with Curl and PHP
提问by John
I'm trying to connect to an API, authenticate a user and then view the user details. This is accomplished by first accessing the login endpoint at
我正在尝试连接到 API,对用户进行身份验证,然后查看用户详细信息。这是通过首先访问登录端点来完成的
http://api.example.com/login/<username>/<password>
to log in and then the following to view user details:
登录,然后执行以下操作以查看用户详细信息:
http://api.example.com/user/
This all works in a web browser. However, once I try to use Curl, the login works fine, but when attempting to view user details, I get back a 401, unauthorized error. I believe this is because Curl isn't saving the session cookies properly? Can someone point out why it isn't working and how to fix it? I've tried searching stack exchange, however, none of the solutions I've tried have worked for my situation. The code I'm using to curl the endpoints is shown below. Thanks!
这一切都适用于网络浏览器。但是,一旦我尝试使用 Curl,登录就可以正常工作,但是在尝试查看用户详细信息时,我会返回一个 401,未经授权的错误。我相信这是因为 Curl 没有正确保存会话 cookie?有人可以指出为什么它不起作用以及如何解决它?我试过搜索堆栈交换,但是,我尝试过的所有解决方案都不适用于我的情况。我用来卷曲端点的代码如下所示。谢谢!
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);
This code will output:
此代码将输出:
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!"}
采纳答案by drew010
You also need to set the option CURLOPT_COOKIEFILE.
您还需要设置选项CURLOPT_COOKIEFILE。
The manual describes this as
该手册将其描述为
The name of the file containing the cookie data. The cookie file can be in Netscape format, or just plain HTTP-style headers dumped into a file. If the name is an empty string, no cookies are loaded, but cookie handling is still enabled.
包含 cookie 数据的文件的名称。cookie 文件可以是 Netscape 格式,也可以只是转储到文件中的普通 HTTP 样式标头。如果名称为空字符串,则不会加载 cookie,但仍启用 cookie 处理。
Since you are using the cookie jar you end up saving the cookies when the requests finish, but since the CURLOPT_COOKIEFILEis not given, cURL isn't sending any of the saved cookies on subsequent requests.
由于您使用的是 cookie jar,您最终会在请求完成时保存 cookie,但由于CURLOPT_COOKIEFILE没有给出,cURL 不会在后续请求中发送任何保存的 cookie。
回答by Scuzzy
You have correctly used "CURLOPT_COOKIEJAR" (writing) but you also need to set "CURLOPT_COOKIEFILE" (reading)
您已正确使用“CURLOPT_COOKIEJAR”(写作)但您还需要设置“CURLOPT_COOKIEFILE”(阅读)
curl_setopt ($ch, CURLOPT_COOKIEJAR, COOKIE_FILE);
curl_setopt ($ch, CURLOPT_COOKIEFILE, COOKIE_FILE);
回答by raveren
This is how you do CURL with sessions
这就是你如何用 session 做 CURL
//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);
}
I've seen this on ImpressPages
我在 ImpressPages 上看到过这个
回答by ficuscr
Yup, often called a 'cookie jar' Google should provide many examples:
是的,通常被称为“cookie jar”谷歌应该提供很多例子:
http://devzone.zend.com/16/php-101-part-10-a-session-in-the-cookie-jar/
http://devzone.zend.com/16/php-101-part-10-a-session-in-the-cookie-jar/
http://curl.haxx.se/libcurl/php/examples/cookiejar.html<- good example IMHO
http://curl.haxx.se/libcurl/php/examples/cookiejar.html<- 恕我直言的好例子
Copying that last one here so it does not go away...
在这里复制最后一个,这样它就不会消失......
Login to on one page and then get another page passing all cookies from the first page along Written by Mitchell
登录到一个页面,然后获取另一个页面,传递第一页中的所有 cookie 由 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);
?>

