首页 新闻 会员 周边 捐助

php使用curl带cookie访问一直失败求助

0
悬赏园豆:50 [已解决问题] 解决于 2014-05-07 10:55

最近需要批量向织梦后台导入一些数据,但是遇到了一个头疼的问题。

环境:xampp + 别人的dede后台。

首先,利用curl发送post请求登录login.php,成功,并且保存了cookie文件。

第二步,post发送数据包到co_get_corule.php,失败,得到登录页面的源码。

于是,尝试简单的get请求,get获取index.php,同上,依旧是cookie没带上的效果。

第三步,检查cookie文件,确实存在,且内容也是正确的。

经过多次重复试验,依旧失败,于是发帖求助。

 

 1 <?php 
 2     header("Content-type: text/html; charset=utf-8");
 3     !extension_loaded('curl') && die('The curl extension is not loaded.');
 4     $cookie_jar = tempnam('./cookies','cookie');//存放COOKIE的文件
 5     
 6     //登陆认证
 7     $url = 'http://localhost/dede/login.php';
 8     
 9 
10     //本来封装了函数,后来一直不成功,于是还原成了最原始的代码积木
11     
12     $post_data='gotopage=index.php&dopost=login&adminstyle=newdedecms&userid=admin&pwd=admin';    
13     
14     $ch = curl_init();
15     
16     curl_setopt($ch, CURLOPT_URL, $url);    
17     curl_setopt($ch, CURLOPT_HEADER, 0);      
18     curl_setopt($ch, CURLOPT_POST, 1);     //设置post方式    
19     curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); // 1相当于return,0相当于echo    
20     
21     curl_setopt($ch,CURLOPT_COOKIESESSION,true);
22     curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); //设置需要post的数据    
23     curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);  //保存cookie信息    
24     
25     curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1); //是否抓取跳转后的页面,1是自动跳转        
26     //curl_setopt($ch, CURLOPT_NOBODY,1); //输出的不包含body部分    
27     
28     $output1 = curl_exec($ch);    
29     
30     //写入结果到文件
31     file_put_contents('login.txt', $output1);
32     
33     curl_close($ch);
34     
35     
36     
37     //这里本来封装了函数,后来一直不成功,于是还原成了最原始的代码积木
38     
39     $url2 = "http://localhost/dede/index.php";
40     $ch2 = curl_init();
41     
42     curl_setopt($ch2, CURLOPT_URL, $url2);
43     curl_setopt($ch2, CURLOPT_HEADER, 0);  
44     
45     curl_setopt ( $ch2, CURLOPT_RETURNTRANSFER, 1 ); // 1相当于return,0相当于echo
46     curl_setopt($ch2, CURLOPT_BINARYTRANSFER, true);   
47     
48     curl_setopt($ch2, CURLOPT_TIMEOUT, 30);    //超时时间30s    
49     curl_setopt($ch2,CURLOPT_COOKIESESSION,true);
50     curl_setopt($ch2, CURLOPT_HTTPGET, 1); // 发送一个常规的get请求
51     curl_setopt($ch2, CURLOPT_AUTOREFERER, 1); // 自动设置Referer   
52     curl_setopt($ch2,CURLOPT_COOKIEFILE,$cookie_jar);//发送cookie文件
53     curl_setopt($ch2, CURLOPT_COOKIEJAR, $cookie_jar);  //保存cookie信息
54     
55     curl_setopt($ch2, CURLOPT_FOLLOWLOCATION,1); //是否抓取跳转后的页面,1是自动跳转
56     //curl_setopt($ch, CURLOPT_NOBODY,1); //输出的不包含body部分
57     
58     $output = curl_exec($ch2);
59     file_put_contents('index.txt', $output);
60     curl_close($ch2);
61     
62     
63     unlink($cookie_jar);
64 ?>

【PS:实在不知道如何验证cookie是否起作用了】

以上是拆掉函数后的原始代码,不具可读性,只求能解决这个坎儿,期待大家的帮忙,谢谢!

< >
分享
最佳答案
0

抓包看下,第二次请求时,COOKIE 是否包含在请求中。

也可以 curl_setopt($ch,CURLOPT_VERBOSE,0L),从输出看下请求和响应的内容。

收获园豆:40
Launcher | 高人七级 |园豆:45050 | 2014-04-30 11:37

不好意思,回复挤成一块了,我截图上传哈。

工程内业编程 | 园豆:124 (初学一级) | 2014-04-30 14:03

@不要呵呵:你这是只是Response,你的 Request 呢?

你第二次发起请求的 Request 的 Header 中应该包含:

Cookie:xxxxxxxxxxxxxxxxxxxxxxxxxx

 

Launcher | 园豆:45050 (高人七级) | 2014-04-30 14:51

@Launcher: 

没有Cookie:xxxx这行。如图:

 

另外,求截php发送的数据包方法。截浏览器的只能截取到 GET:/caiji.php ***

谢谢

工程内业编程 | 园豆:124 (初学一级) | 2014-04-30 15:06

@不要呵呵: 你用 CURLOPT_HTTPHEADER 把那个 COOKIE 加上。

Launcher | 园豆:45050 (高人七级) | 2014-04-30 15:12

@Launcher: 

$header[]= 'Cookie: menuitems=xxxxxxxx...";

curl_setopt($ch, CURLOPT_HEADER, 1); 

curl_setopt($ch, CURLOPT_HTTPHEADER,$header);

手动添加cookie后,正常进入了需要登陆的页面了。但是在firebug里面依旧看不到我发送的cookie

Cookie:xxxxxxxxxxxxxxxxxxxxxxxxxx

现在的疑问:

1、手动设置cookie就能成功,而调用api的却没成功

2、firebug里面看不到我手动设置的cookie头

3、curl帮我保存的cookie文件,session过期时间为何是1981年呢?

感激不尽!

工程内业编程 | 园豆:124 (初学一级) | 2014-04-30 15:46

@不要呵呵: 看不到是不可能的,是你抓取的包有问题。如果是 Windows 系统,可以使用 Fiddler 和 Microsoft Network Monitor 来抓去包,使用前者的话,你需要在 libcurl 中设置 HTTP 代理为本机,端口号可以从 Fiddler 的选项中找到。

 

你说的使用 API 的方式,应该是指使用 CURLOPT_COOKIEFILE 设置后不起作用吧!首先你得检查使用 CURLOPT_COOKIEJAR 后,是否保存了 COOKIE,注意只有调用了 curl_easy_cleanup 后才会保存。其次,在使用 CURLOPT_COOKIEFILE 时,你需要检查读取的文件中是否有 COOKIE 信息,你可以进入源码调试下,在处理 CURLOPT_COOKIEFILE 时,libcurl 是否读取到了你设置的 COOKIE。

 

另外 HTTP Response Header 中的 Expires 跟 SESSION 无关,它是用来表示响应的缓存有效期的。

Session

Launcher | 园豆:45050 (高人七级) | 2014-04-30 16:02

@Launcher: 

感谢你在百忙中抽空帮我。

刚才我做了个对比:

1、使用Microsoft Network Monitor 监听apache发送的数据包

2、使用Microsoft Network Monitor 截获ie登录目标后台

3、使用Microsoft Network Monitor 截获firefox登录目标后台

由第一点得到:cookie确实由curl加入到了http请求头部里面,具体数据如下:

Cookie:  PHPSESSID=b2qdqolekobbcq9p9s0i02onj6; DedeLoginTime__ckMd5=160a742df0464593; DedeLoginTime=1398868032; DedeUserID__ckMd5=adc11e494632c401; DedeUserID=1

firefox的cookie行如下:

Cookie: menuitems=1_1%2C2_1%2C3_1; Hm_lvt_2310b8fc76ab1532b04dc0f587e6a640=1385623511; pgv_pvi=6713670656; Hm_lvt_2fe99d3e28a6deb7b6f59b7add268f7a=1385623516; DedeUserID=1; DedeUserID__ckMd5=adc11e494632c401; DedeLoginTime=1398868517; DedeLoginTime__ck

 

IE的cookie头如下:

Cookie:  menuitems=1_1%2C2_1%2C3_1; DedeUserID=1; DedeUserID__ckMd5=adc11e494632c401; DedeLoginTime=1398863428; DedeLoginTime__ckMd5=11e6c4db51052b1e;PHPSESSID=a12qtpfhu9vnbv8dd3c6b7qvn6; path=/

 

经过对比试验发现:

menuitems、pgv_pvi …… 这些都不影响正常访问。

关闭firefox和ie,手工把这3个cookie加入到代码中访问,发现浏览器的cookie都能正常访问,而curl获取的却不行。

对比手工加入浏览器cookie访问更新的cookie文件,发现:

正常访问更新cookie后,PHPSESSID 这一整行在cookie里面找不到了。

实在想不通这是怎么回事儿了。麻烦再指点一二。谢谢!

工程内业编程 | 园豆:124 (初学一级) | 2014-04-30 22:45

@不要呵呵: 因为没法测试,所以我还是讲清楚流程,你自己还是需要进入 libcurl 的源码跟踪调试下。

首先,客户端发起一个登录的请求,服务器通过验证后,返回的响应的 HEADER 中应该包括:

Set-Cookie: PHPSESSID=a12qtpfhu9vnbv8dd3c6b7qvn6; path=/

这是一个检查点,就是检查返回的响应中是否有 Set-Cookie,可以这样:

curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION,....),然后在回调函数中观察 Set-Cookie 标头。

在确定包含 Set-Cookie 后,调用 curl_easy_cleanup 后,看使用 CURLOPT_COOKIEJAR 后保存的 Cookie 文件中是否包含正确的 Cookie。如果没有包含正确的 Cookie,那么你需要在 libcurl 的源码中搜索 CURLOPT_COOKIEJAR,找到 libcurl 如何将 Set-Cookie 标头的内容写入文件的。

Launcher | 园豆:45050 (高人七级) | 2014-05-04 09:26

@Launcher: 最近比较忙,没来的及回复哈,见谅。

同样的代码,使用C++调用libcurl居然成功了。

现在还没完全弄明白是什么原因,不过成功解决了问题。

具体细节问题我日后再慢慢调试吧,非常谢谢你的帮助!

工程内业编程 | 园豆:124 (初学一级) | 2014-05-07 10:54
其他回答(1)
0

cookie所属域名看了没,跨域cookie传不过去的

收获园豆:10
吴瑞祥 | 园豆:29449 (高人七级) | 2014-04-30 10:18

以前也做个类似的案例,都很顺利,但是这次的不可以。麻烦吴哥针对这个例子给指点一二,谢谢!

支持(0) 反对(0) 工程内业编程 | 园豆:124 (初学一级) | 2014-04-30 14:09

@不要呵呵: 话说为什么COOKIE会是文件,

你看下第一次的回话ID和第二次的回话ID是不是同一个

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2014-04-30 14:42

@吴瑞祥: 非常谢谢你的帮助!

支持(0) 反对(0) 工程内业编程 | 园豆:124 (初学一级) | 2014-05-07 10:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册