【问题标题】:PHP cURL is holding onto session cookiesPHP cURL 持有会话 cookie
【发布时间】:2015-06-24 06:29:20
【问题描述】:

所以这很奇怪。我正在制作一个 cURL 登录脚本,我需要我的 cookie 正是我发送给 cURL 的内容。但似乎 cURL 在内存中保留了旧的 cookie,即使在 cookie 文件被完全截断之后也是如此。

在下面的输出中,请注意我正在尝试点击 amazon.co.uk,但我之前来自 amazon.com 的 cookie 仍位于 cookie 文件的顶部。这足以让亚马逊不再让我保持登录状态。所以我需要新鲜的饼干。

现在,您看到的第一个 cookie 输出是起点。 每次我刷新页面时都会发生这种情况。 尽管最终的 cookie 输出不是这个。这只是 amazon.co.uk cookie。

其他 cookie “工作”的原因是因为在登录页面上(您会看到“需要清理会话”。我正在调用 curl_setopt($ch, CURLOPT_COOKIESESSION, true);,它仅正确发送文件中的 cookie。

但在那之后,当我不再调用它时,它会返回到这些存储的 cookie。我不能每次都调用 COOKIESESSION,因为我需要它记住从请求到请求的 cookie。

所以基本上,我只需要一种方法来清除 cookie 的 cURLs 内存,或者类似的东西。在你说“删除文件”之前,你可以从输出中看到我正在清除 cookie 文件。

string(125706) "
string(78) "https://sellercentral.amazon.co.uk/gp/fba/core/data/collections/shipments.html"
string(12) "need to init"
string(1704) "# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

.amazon.com TRUE    /   FALSE   1429875358  session-id-time 1429858800l
.amazon.com TRUE    /   FALSE   1429875358  session-id  181-0028548-4275101
.amazon.com TRUE    /   FALSE   1429875532  ubid-main   191-9297218-7050950
.amazon.com TRUE    /   FALSE   1429875358  session-token   cL5vcznqgzk2RwhZIFZjSepKiznVnNcdv1Uh/FiLV8i0QuxpPEEx5D94imjktXu69QOdfQuQX8chNhvB8sR9KI4ZgJBWWlMnFOepyO6/+wtH9GOtH+1WMZQKHp8fqGJlpMtT8XMwKUx+hnuYRPnheq54s5Q1fQX5HJ4wS3KE4UVHAady2H4ugSsIi+O33zL1d3eWN4TnbX4nxiHqIqFs4Q8GGCYVEwOrbcB1KH3FCohbrwQPXNN7igf6jQXI++h0N0dJTv781sU=
.amazon.com TRUE    /   FALSE   2059990558  x-main  "i6iLU3A?45qEpvgw@NNzGTsxqqOvwryX"
.amazon.com TRUE    /   TRUE    2059990557  at-main 5|7HZSLL/JbN/aGiGYXo/uxjxNFyLucyEmxBCKkR4QoU06R5NF4I1eNekoJpsyE2hkx5FrSI3dP5DuaolT5D48jdz6NLwDmYdKzovka+5DJTHuRuVmzBVVkW2g40uhZlRlaHJmewKWCjmoyi+azkQswRDRmfyAICX+hBrRfUwJRwQqeOhQGc6dujYHDBiv8nxcQFciY9G+7au3zYAGof+CepYeiWk4xuQmBLobVAci10frgDxdgV7OdJOSVaHz2UtykTQ+F4V4hNzFwclsv9ranLMSM5KH9tys
.amazon.com TRUE    /   TRUE    0   sess-at-main    "GR5GAfuX5U+vC3ayUz3LIUs7+o414SBlsEA1rVMyvvA="
.amazon.com TRUE    /   FALSE   2059990557  lc-main en_US
.amazon.co.uk   TRUE    /   FALSE   1429875575  session-id-time 1429858800l
.amazon.co.uk   TRUE    /   FALSE   1429875575  session-id  276-1602919-0207204
.amazon.co.uk   TRUE    /   FALSE   1429876234  ubid-acbuk  277-6716334-7531852
.amazon.co.uk   TRUE    /   FALSE   1429875881  session-token   gVQymTdZsxCD0I/aObEZCLmujDKZGjQ48lGc34xaW6i45XVIonC1YK014YrFqVvNG2qurp1xmGrtCHcuVQx2tSQ7LlYpr+srdgyKvj/pCcW6CxR0azqQsU9wYW3BxXqZnQDQnqVmYaGpY0eB19BOTShppMKGnPhzMkgy/UFVuoeGsngx0tz8iWFMy6qTZFqibPoMvFmpsdsL8GhbVn6sy++vUUBeQhVgyzktWEfjRXdzZw32t/SOCA==
"
string(21) "unexpected login page"
string(78) "https://sellercentral.amazon.co.uk/gp/fba/core/data/collections/shipments.html"
string(12) "need to init"
string(0) ""
string(25) "no cookies, need to login"
string(51) "https://sellercentral.amazon.co.uk/gp/homepage.html"
string(0) ""
string(28) "on login, need clean session"
string(44) "https://sellercentral.amazon.co.uk/ap/widget"
string(270) "# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

.amazon.co.uk   TRUE    /   FALSE   1429876317  session-id-time 1429858800l
.amazon.co.uk   TRUE    /   FALSE   1429876317  session-id  278-1385775-5645645
"
string(112) "https://sellercentral.amazon.co.uk/gp/utilities/set-rainier-prefs.html?ie=UTF8&url=&marketplaceID=A1F83G8C2ARO7P"
string(1212) "# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

.amazon.co.uk   TRUE    /   FALSE   1429876318  session-id-time 1429858800l
.amazon.co.uk   TRUE    /   FALSE   1429876318  session-id  278-1385775-5645645
.amazon.co.uk   TRUE    /   FALSE   1429876318  ubid-acbuk  279-4986453-7111520
.amazon.co.uk   TRUE    /   FALSE   1429876318  session-token   YpneIOOGKiqQ8x/E/soTTmUAym3tXUWGtjXKYWnAONOkcHENmQxMDD3zTWjgtLN9b/em0xBTPoYMpECUcR38rZlf2Vu1a2TOBNsi2hpTjageCvIM9noPlEq0TBrgdOEfGl354j0+dIfTHM4ObUF2nzY2UBubZoi3X77MBcpLel+rjjCFeTCwhmNFbru5dyalIRn1UyVAdsB3PIEk+saDDbf2HRMUFP7hdaCaBhKwb5tpyvpA1xrk2XJXm2dre2FE1MKsgWFwt1c=
.amazon.co.uk   TRUE    /   FALSE   2059991518  x-acbuk 3IkDIKmc71d9lKFefDy7ATw1QKYl8545
.amazon.co.uk   TRUE    /   TRUE    2059991518  at-acbuk    "5|/QlP2Fp+YlPLm1O0znctkujc6sMDGnEGxbqVjtrNehg2P98QG1vCFOkKxChCaUJzPmQSS4C/87WM0XC30721BVwFLpKRa9FIS9sUtlZJh8m07RHhC2vBspsYjZ710LfM/cHCHKXdBmXlHZ8CLNO55ff4oYRI5NnaFKu8dx2xSBdwAzYydTqlQhrOKE0RAolHBJgIVngWDlw42kDY79FOciZP7ray/qSR/eceAPfJfzIV0t/vKC/vWpNlOQBs/FTmvWmEMZtSoAUWlgPeIiUw+g=="
.amazon.co.uk   TRUE    /   TRUE    0   sess-at-acbuk   "9EziH1irfB0flBfODA2zw+lVgvo4OmENH4XM3kxEnpg="
.amazon.co.uk   TRUE    /   FALSE   2059991518  lc-acbuk    en_US

【问题讨论】:

    标签: php session curl cookies


    【解决方案1】:

    更新

    遇到麻烦时,我经常将FOLLOWLOCATION设置为false:

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    

    如果有重定向,您可以看到正在发生的事情,并且需要获取在重定向 URL 的响应标头中设置的 cookie,然后 FOLLOWLOCATION 必须设置为 false。

    当 curl URL 将您带到重定向时,curl_getinfo 将获得重定向位置 URL。

    $status = intval(curl_getinfo($ch,CURLINFO_HTTP_CODE));
    if ($status > 299 && $status < 400){
      $url= curl_getinfo($ch,CURLINFO_REDIRECT_URL );
    }
    // update cookies, do not clear `cookies()`;
    

    当遇到困难时,我会使用这些选项来获取响应和响应标头。响应标头将在 curl_exec() 数据中返回。请求标头将由curl_getinfo()返回

    curl_setopt($ch, CURLOPT_VERBOSE, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
    curl_setopt($ch, CURLINFO_HEADER_OUT, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    
    
    $data = curl_exec($ch);
    if (curl_errno($ch)){
        $data .= 'Retreive Base Page Error: ' . curl_error($ch);
    }
    else {
      $info = rawurldecode(var_export(curl_getinfo($ch),true));
      $data = curl_exec($ch);
      $skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE)); 
      $requestHeader= substr($data,0,$skip);
      $data =  substr($data,$skip);
      $filename = parse_url($url, PHP_URL_HOST);
      $filename .= parse_url($url, PHP_URL_PATH) . '.txt';
      $fp = fopen($filename,'w');
      fwrite($fp,$info\n$data");
      fclose($fp);
    
      $data =  substr($data,$skip);
    }
    

    标题和 HTML 都存储在文件中。然后,您可以查看 HTTP 标头、HTML 和 JavaScript。有时 cookie 是由 JavaScript document.cookie 设置的,或者是使用 window.location 重定向的页面,或者是使用 JS 单击 HTML 表单的提交按钮。在这些情况下,可能需要从 curl 数据中抓取 cookie 和/或重定向位置。


    然后我使用 FireFox Inspector 或 Chrome 开发工具。

    我转到“网络”标签

    在 FireFox 中,我转到“设置”并打开“启用持久日志”
    在 Chrome 中,我单击“网络”选项卡上的“保留日志”

    然后我使用浏览器去任何我想 curl 去的地方。

    现在我可以看到每个请求和响应,包括重定向,并将它们与保存的标头进行比较。


    当您需要标题与保存的浏览器标题完全相同时:

    创建一个数组来放置请求标头键值
    使用您上传的请求标头中的确切内容填写请求数组。
    示例:

    $request = array();
    $request[] = "Host: www.example.com";
    $request[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    $request[] = "User-Agent: MOT-V9mm/00.62 UP.Browser/6.2.3.4.c.1.123 (GUI) MMP/2.0";
    $request[] = "Accept-Language: en-US,en;q=0.5";
    $request[] = "Connection: keep-alive";
    $request[] = "Cache-Control: no-cache";
    $request[] = "Pragma: no-cache";
    

    添加到卷曲:

    curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
    

    很多时候,使用移动版本要容易得多。很多时候桌面版页面需要 JavaScript 而移动版不需要。我使用带有用户代理切换器的 FireFox,使用旧的摩托罗拉用户代理来检索标题和 HTML。然后我在 curl 的HTTPHEADER 中使用相同的用户代理:

    request[] = 'User-Agent: MOT-V9mm/00.62 UP.Browser/6.2.3.4.c.1.123 (GUI) MMP/2.0
    

    更新结束


    我发现 curl 的 cookie jar 有问题,所以我编写了自己的例程。
    对于这个CURLOPT_HEADER 必须为真。

     curl_setopt($ch, CURLOPT_HEADER, true);
    
      $data = curl_exec($ch);
      $skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE)); 
      $requestHeader= substr($data,0,$skip);
      $data =  substr($data,$skip);
      $e = 0;
      while(true){
        $s = strpos($requestHeader,'Set-Cookie: ',$e);
        if (!$s){break;}
        $s += 12;
        $e = strpos($requestHeader,';',$s);
        $cookie = substr($requestHeader,$s,$e-$s) ;
        $s = strpos($cookie,'=');
        $key = substr($cookie,0,$s);
        $value = substr($cookie,$s);
        $cookies[$key] = $value;
      }
    

    然后使用 $cookies[]:

     $cookie = '';
     $show = '';
     $delim = '';
     foreach ($cookies as $k => $v){
       $cookie .= "$delim$k$v";
       $delim = '; ';
     }
    

    然后使用 $cookie:

    curl_setopt($ch, CURLOPT_COOKIE, $cookie );
    

    【讨论】:

    • 试图让它工作,请注意我的标题说“Set-cookie”而不是 Set-Cookie。要用 stripos 替换你的 strpos
    • 使用stripos(不区分大小写)而不是strpos,那么它可以同时使用两者。这个我用了很多,从来没有遇到过问题,所以一定不会遇到小案例c。
    • 在 while 循环中也使用了 $head,但从未定义。那应该是 $requestHeader 吗?
    • 那应该是requestHeader,我把head改成requestHeader这样对其他人来说会更明显。我的代码使用 $head
    • 此外,如果没有 === false,您将无法检查 strpos 上的布尔值。你在那里有一个无限循环。介意更新这 2 件事(=== false 和 $head 让其他人看到这个?)
    猜你喜欢
    • 2012-03-29
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多