【问题标题】:Invalid cookies recieved from CURL request and file_get_contents从 CURL 请求和 file_get_contents 收到的 cookie 无效
【发布时间】:2018-06-22 13:19:42
【问题描述】:

我在尝试使用 file_get_contentscurl 捕获 cookie 时收到无效的 cookie 字符串。直接从浏览器浏览时收到的 cookie 有效/有效。但是,从file_get_contentscurl 捕获的cookie 似乎无效。

我正在尝试像这样从file_get_contents 捕获

 $context =      array(
  'http' => array(
   'method' => 'GET',
   'header' => array('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*\/*;q=0.8', 'User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/63.0.3239.84 Chrome/63.0.3239.84 Safari/537.36'),
  )
 );

   $cxContext = stream_context_create($context);


    file_get_contents($url, false, $cxContext);
    $cookies = array();

    foreach ($http_response_header as $hdr) {
    if (preg_match('/^Set-Cookie:\s*([^;]+)/', $hdr, $matches)) {
        $cookies = $matches[1];
    }

}
return $cookies;

我尝试通过设置标头来解决这个问题,但返回的 cookie 总是过期或根本无效。

但是,通过浏览器,我得到的 cookie 始终是有效的。

任何人都遇到过类似的问题,不知道如何解决这个问题。

【问题讨论】:

  • 您提到了 curl,但您没有在您提供的代码中使用 curl。也没有任何迹象表明正在使用任何类型的 cookie 罐(用于存储 cookie,以便您可以将其重新发送到服务器,这样服务器就不会每次都为您生成新的)。您还提到返回的 cookie 要么“过期要么无效”——是什么?它们有时有效但已过期,或者有时未过期但无效?这里的“无效”是什么意思?
  • @jhilgeman cookie 只是无法按要求通过身份验证。使用 curl 存储在 cookie jar 中的 cookie 无法通过身份验证。但是,如果我复制/粘贴 cookie - 保存在浏览器中的那个,它就会通过身份验证。很难用语言表达,但 curl / file_get_contents 请求以某种方式被过滤,并且发送的 cookie 字符串似乎无效
  • 您指的是哪种身份验证?您的示例代码中没有显示任何身份验证措施。
  • 哦,等等 - 你说“无效”cookie 是被服务器拒绝的 cookie 值。也许问题不在于 cookie 的存储,而在于原始 cookie 的请求方式。如果您尝试模拟浏览器,则需要准确地执行其步骤(例如,点击登录页面,然后 POST 登录表单数据等...)。
  • 还值得一提的是,越来越多的网站正在使用 Javascript 作为其身份验证方案的一部分,以便浏览器能够正确解释 JS 并更新表单数据,而像这样基于脚本的方法将错过在 JS 上并发布无效数据。如果没有完整的示例,很难确定。

标签: php cookies http-headers file-get-contents


【解决方案1】:

我的上述评论中有几个未解决的问题,但我将分享这段代码以作为示例。这是我过去用作使用 cURL 进行浏览器仿真的基类:

<?php
if(!function_exists("curl_init")) { throw new Exception("CurlBrowser requires the cURL extension, which is not enabled!"); }
class CurlBrowser
{
    public $userAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0";
    /*
    Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0
    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1");
    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0 
    */

    public $cookiesFile = null;
    public $proxyURL = null;
    public $saveLastOutput = "";
    public $caBundle = "cacert.pem";
    public $httpHeaders = array();

    public function __construct($UseCookies = true)
    {
        if(is_bool($UseCookies) && $UseCookies)
        {
            $this->cookiesFile = dirname(__FILE__)."/cookies.txt";
        }
        elseif(is_string($UseCookies) && ($UseCookies != ""))
        {
            $this->cookiesFile = $UseCookies;
        }
    }

    public function SetCustomHTTPHeaders($arrHeaders)
    {
        $this->httpHeaders = $arrHeaders;
    }

    public function SetProxy($proxy)
    {
        $this->proxyURL = $proxy;
    }

    public function Get($url)
    {
        return $this->_request($url);
    }

    public function Post($url,$data = array())
    {
        return $this->_request($url,$data);
    }

    private function _request($form_url,$data = null)
    {
        $ch = curl_init($form_url);

        // CA bundle
        $caBundle = $this->caBundle;
        if(file_exists($caBundle))
        {
            // Detect and convert relative path to absolute path
            if(basename($caBundle) == $caBundle)
            {
                $caBundle = getcwd() . DIRECTORY_SEPARATOR  . $caBundle;
            }
            // Set CA bundle
            curl_setopt($ch, CURLOPT_CAINFO, $caBundle);
        }

        // Cookies
        if($this->cookiesFile !== null)
        {
            curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookiesFile);
            curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookiesFile);
        }

        // User Agent
        curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent); 

        // Misc
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_ENCODING, "gzip, deflate");

        // Optional proxy
        if($this->proxyURL !== null)
        {
            curl_setopt($ch, CURLOPT_PROXY, $this->proxyURL);
        }

        // Custom HTTP headers
        if(count($this->httpHeaders))
        {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $this->httpHeaders);
        }

        // POST data
        if($data !== null)
        {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }

        // Run operation
        $result = curl_exec($ch);

        if($result === false)
        {
          throw new Exception(curl_error($ch));
        }
        else
        {
            if(!empty($this->saveLastOutput))
            {
            file_put_contents($this->saveLastOutput,$result);
          }
          return $result;
        }
    }
}
?>

你会这样使用它:

<?php
$browser = new CurlBrowser();
$html = $browser->Get("https://....");
...etc...

我的直觉是,您只是在原始代码中缺少一个 cookie 罐,但这主要是基于直觉,因为我们目前没有您的所有问题代码。

【讨论】:

    猜你喜欢
    • 2013-12-23
    • 1970-01-01
    • 2012-07-21
    • 2014-09-18
    • 2023-03-19
    • 1970-01-01
    • 2018-06-03
    • 2013-06-13
    • 2019-03-09
    相关资源
    最近更新 更多