提问者:小点点

Curl无法正确识别cookie中的expires值


我正在尝试使用 curl 在 pinterest.com 上执行登录。我得到了以下请求-响应-流:

  1. GET请求登录表单并清除隐藏字段(csrftoken)
  2. POST请求登录凭据(邮件和密码)和scraped csrftoken
  3. 接收会话Cookie以进行登录

使用Curl,我可以看到以下发送和接收的标头:

 GET /login/?next=%2F HTTP/1.1
 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
 Host: pinterest.com
 Referer:
 Accept: text/html,application/xhtml+xml,application/xml,*/*
 Accept-Language: de-de,en-us
 Connection: keep-alive

 HTTP/1.1 200 OK
 Content-Type: text/html; charset=utf-8
 Date: Tue, 10 Apr 2012 15:03:24 GMT
 ETag: "45d6a85f0ede46f13f4fc751842ce5b7"
 Server: nginx/0.8.54
 Set-Cookie: csrftoken=dec6cb66064f318790c6d51e3f3a9612; Max-Age=31449600; Path=/
 Set-Cookie: _pinterest_sess="eJyryMwNcTXOdtI3zXcKNq0qznIxyXVxK/KqSsy3tY8vycxNtfUN8a3yc3E09nXxLPdztLVVK04tLs5MsfXNAopVpVf6VnlW+Qba2gIAuqgZIg=="; Domain=pinterest.com; HttpOnly; expires=Tue, 17-Apr-2012 15:03:24 GMT; Max-Age=1334675004; Path=/
 Vary: Cookie, Accept-Encoding
 Content-Length: 4496
 Connection: keep-alive

因此,在第1步之后,设置了两个cookie csrfToken和_pinterest_sess。但是查看cookiejar文件(我使用CURLOPT_COOKIEFILE和CURLOPT_COOKIEJAR让curl处理cookie处理)会显示以下内容:

   # Netscape HTTP Cookie File
   # http://curl.haxx.se/rfc/cookie_spec.html
   # This file was generated by libcurl! Edit at your own risk.

   pinterest.com        FALSE        /        FALSE        1365519805        csrftoken        dec6cb66064f318790c6d51e3f3a9612
   #HttpOnly_.pinterest.com        TRUE        /        FALSE        -1626222087        _pinterest_sess        "eJyryMwNcTXOdtI3zXcKNq0qznIxyXVxK/KqSsy3tY8vycxNtfUN8a3yc3E09nXxLPdztLVVK04tLs5MsfXNAopVpVf6VnlW+Qba2gIAuqgZIg=="

首先要注意的是_pinterest_sesscookie行前面的#HttpOnly_。我只是假设curl可以很好地处理这个问题。但是进一步观察,可以看到一个负值被设置为到期日期:-1626222087

我不知道这是从哪里来的,因为cookie设置为“过期=星期二,17-Apr-2012 15:03:24 GMT”(大约是未来的7天,从今天开始计算)。

在下一次请求中,_pinterest_sesscookie不会由curl设置:

 POST /login/?next=%2F HTTP/1.1
 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
 Host: pinterest.com
 Referer: https://pinterest.com/login/?next=%2F
 Cookie: csrftoken=dec6cb66064f318790c6d51e3f3a9612
 Accept: text/html,application/xhtml+xml,application/xml,*/*
 Accept-Language: de-de,en-us
 Connection: keep-alive
 Content-Length: 123
 Content-Type: application/x-www-form-urlencoded

 HTTP/1.1 302 FOUND
 Content-Type: text/html; charset=utf-8
 Date: Tue, 10 Apr 2012 15:05:26 GMT
 ETag: "d41d8cd98f00b204e9800998ecf8427e"
 Location: http://pinterest.com/
 Server: nginx/0.8.54
 Set-Cookie: _pinterest_sess="eJzLcssPCy4NTclIjvAOrjQzyywoCChISgvLDi+2tY9PrSjILEottvUN8a3yc4k09gtxrfRLt7VVK04tLs5MAYonV/qGeFb4ZkWW+4LES4tTi+KBEv4u6UZ+WYEmvlm+QOxZ6R/iWOEbEmgLAKNfJps="; Domain=pinterest.com; HttpOnly; expires=Tue, 17-Apr-2012 15:05:26 GMT; Max-Age=1334675126; Path=/
 Vary: Cookie
 Content-Length: 0
 Connection: keep-alive

在响应中,设置了另一个_pinterest_sess cookie,因为curl没有发送最后一个。

目前,我不知道我是否做错了什么,或者curl是否无法正确解析cookie中的expires值。

任何帮助都将不胜感激:)

//再编辑一点:根据http://open source . apple . com/source/curl/curl-57/curl/lib/cookie . c使用函数curl_getdate()提取日期。关于该函数的文档列出了一些示例(http://curl . haxx . se/libcurl/c/curl _ getdate . html):

    < li >太阳,1994年11月6日08:49:37 GMT < Li > 94年11月6日星期日08:49:37 GMT 孙1994年11月6日08时49分37秒 < Li > 1994年11月6日08:49:37 GMT < Li > 94年11月6日08:49:37 GMT < Li > 1994年11月6日08时49分37秒 < Li > 1994年11月6日08时49分37秒 < Li > 94年11月6日08时49分37秒 < li>1994年11月6日08:49:37 GMT 1994年11月6日08时49分37秒 < Li > 94年11月6日星期日08:49:37 <李> 1994年11月6日 94年11月6日 94年11月6日星期日 <李> 1994。11月6日 < Li > 1994年11月6日星期日/GMT 孙,1994年11月6日欧洲中部时间08:49:37 < li >美国东部时间1994年11月6日08:49:37 孙,2004年9月12日15:05:58 -0700 < Li > 2004年9月11日星期六21:32:11 0200 < li>20040912 15:05:58 -0700 < li>20040911 0200

没有一个与上述到期日期“2012年4月17日,星期二,15:03:24 GMT”匹配,因为所有带连字符的示例都只使用2位数的年份。。


共3个答案

匿名用户

由于32位有符号整数值的限制,您的计算机遇到问题。

服务器设置一个最大年龄为1334675004秒的cookie。

Max-Age=1334675004

您在这里发布了您的问题@2012-04-10 15:13:24Z。这是一个UNIX时间戳1334070804。如果将1334675004添加到其中,并且在进行整数往返时考虑32位整数限制2147483647,则会得到:-1626221485:

  1334070804
+ 1334675004
------------
 -1626221485

如数字所示,看起来服务器确实误解了Max-Age属性,如果您将每个值相互分散,则大约有7天的增量(以秒为单位)(604200=~6.99天,差异是因为cookie设置早于您在此处发布问题)。然而,Max-Age是秒的增量,而不是绝对的UNIX时间戳。

尝试使用您的PHP版本提升PHP_INT_MAX,或针对64位进行编译,这应该可以防止出现负数。然而,服务器仍然无法计算最大年龄。你可能想联系pinterest。com并报告问题。

匿名用户

看来< code>pinterest.com未正确使用< code>Max-age,这就是curl删除此cookie的原因。

在您的示例中,Max age包含2012年4月17日星期二15:03:24 GMT的时间戳,而它应该包含从请求时间到该日期的秒数-604800

curl正在做的是将最大年龄值添加到当前时间戳并将其保存为有符号的32位整数,因此-1626222087

至于解决方案-您可以尝试联系pinterest并报告错误。

匿名用户

实际上,您不需要联系pinterest站点,因为它不需要发送回服务器cookie max-age(如果您使用cookie的时间很短,或者您可以计算自己正确的max-age)。只要翻转减号,它就会工作,这意味着它将被发送回服务器。这并不是你必须做的全部。有时,根据所呈现的登录页面,您还必须分割隐藏字段(CSRF令牌所在的位置,并且必须与cookie中的相同令牌值匹配)。此外,有时还需要更改cookie(重置cookie值)。因此,pinterest网站使用自动登录工具和屏幕抓取越来越难登录。最近,他们改变了网站的功能。因此,上述所有要点现在都不起作用。实际上,您并不知道他们什么时候会更改登录的工作方式。当变化发生时,你必须试着“猜测”。实际上,这种态度不应该针对开发人员,而应该针对那些威胁系统安全的人(入侵者)。你也必须考虑上述几点的合法性问题。Pinterest有API(虽然现在已经关闭),所以这是使用该API的最佳和最正确的方式(请参阅https://github.com/kellan/pinterest.api.php). 在这里,您以json格式交换消息。使用m.pinterest的最后一个选项。com是一个面向移动设备的网站,它努力使用parceone登录html作为隐藏的输入字段,并用正确的值重新提交表单(要使用它,您也会再次面临合法性问题)。在使用类似curl的工具之前,请咨询pinterest站点,或者等到pinterest api启动后再使用。是的,系统中有一些改进,比如获得json响应,从而结束了屏幕抓取,但这并不意味着全新的api。同时,现在他们(似乎)实现了web服务、restful、api和接受ajax请求,这再次朝着积极的改进迈出了一步。网上有很多关于这个问题的讨论,所以请参考他们了解详细信息。