4

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

  1. GET-请求登录表单并抓取隐藏字段(csrftoken)
  2. POST-请求登录凭据(邮件和密码)和抓取的 csrftoken
  3. 接收 Session 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_sess cookie 行之前的 #HttpOnly_。我只是假设 curl 处理得很好。但进一步看,可以看到将负值设置为到期日期:-1626222087

我不知道这是从哪里来的,因为 cookie 设置为“expires=Tue,2012 年 4 月 17 日 15:03:24 GMT”(大约 7 天后,从今天开始计算)。

在下一个请求中,curl 不会设置 _pinterest_sess cookie:

 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 中的过期值。

任何帮助将不胜感激 :)

// 编辑还有一件事:根据http://opensource.apple.com/source/curl/curl-57/curl/lib/cookie.c函数 curl_getdate() 用于提取日期。该函数的文档列出了一些示例(http://curl.haxx.se/libcurl/c/curl_getdate.html):

  • 1994 年 11 月 6 日星期日 08:49:37 GMT
  • 格林威治标准时间 94 年 11 月 6 日星期日 08:49:37
  • 1994 年 11 月 6 日星期日 08:49:37
  • 格林威治标准时间 1994 年 11 月 6 日 08:49:37
  • 格林威治标准时间 94 年 11 月 6 日 08:49:37
  • 1994 年 11 月 6 日 08:49:37
  • 1994 年 11 月 6 日 08:49:37
  • 94 年 11 月 6 日 08:49:37
  • 格林威治标准时间 1994 年 11 月 6 日 08:49:37
  • 08:49:37 94 年 11 月 6 日
  • 94 年 11 月 6 日星期日 08:49:37
  • 1994 年 11 月 6 日
  • 94 年 11 月 6 日
  • 94 年 11 月 6 日星期日
  • 1994.11.6
  • 太阳/十一月/6/94/格林威治标准时间
  • 1994 年 11 月 6 日星期日 08:49:37 CET
  • 美国东部时间 1994 年 11 月 6 日 08:49:37
  • 2004 年 9 月 12 日星期日 15:05:58 -0700
  • 2004 年 9 月 11 日星期六 21:32:11 +0200
  • 20040912 15:05:58 -0700
  • 20040911 +0200

它们都不符合上述到期日期“Tue, 17-Apr-2012 15:03:24 GMT”,因为所有带有连字符的示例仅使用 2 位数年份。

4

3 回答 3

3

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

服务器在未来设置一个Max-Age为 1334675004 秒的 cookie。

Max-Age=1334675004

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

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

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

尝试PHP_INT_MAX使用您的 PHP 版本进行提升,或针对 64 位进行编译,这应该可以防止出现负数。但是,服务器的 max-age 计算仍然中断。您可能想联系 pinterest.com 并报告问题。

于 2012-04-10T16:58:05.790 回答
1

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

从您的示例中,Max-age包含时间戳Tue, 17-Apr-2012 15:03:24 GMT,而它应该包含从请求时间到此日期的秒数 - 604800(从请求时间 - 标头判断Date

curl 所做的是将Max-age值添加到当前时间戳并将其保存为带符号的 32 位整数,因此-1626222087.

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

于 2012-04-10T16:58:57.687 回答
0

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

于 2013-07-15T08:46:16.630 回答