【问题标题】:How to let Curl use same cookie as the browser from PHP如何让Curl使用与PHP浏览器相同的cookie
【发布时间】:2010-11-10 09:55:36
【问题描述】:

我有一个 PHP 脚本,它代表浏览器执行 HTTP 请求并将响应输出到浏览器。问题是当我单击此页面上浏览器的链接时,它会抱怨 cookie 变量。我假设它需要网站的浏览器 cookie。

如何拦截并转发到远程站点?

【问题讨论】:

    标签: php curl cookies


    【解决方案1】:

    Cookie 通常与 HTTP 请求标头一起发送,例如

    Host stackoverflow.com
    User-Agent ...
    Accept-Language en-us,en;q=0.5
    Referer http://stackoverflow.com/unanswered
    Cookie bla=blabla;blubb=blu
    

    所以我想只需要修改标题中的 cookie 部分。

    【讨论】:

      【解决方案2】:

      来自curl_setopt

      默认情况下,libcurl 始终存储和加载所有 cookie,无论它们是否是会话 cookie。

      但是您可能需要直接设置 cookie,可以使用:

      curl_setopt($ch, CURLOPT_COOKIE, 'foo=bar');
      

      这与 Set-Cookie HTTP 标头相同。检查你没有使用curl_setopt($ch, CURLOPT_COOKIESESSION, true),因为这会使 libcurl 忽略一些 cookie。

      【讨论】:

      • 我最近发现“默认情况下,libcurl 总是存储和加载所有 cookie”的注释似乎在 PHP 5.3.8 中是错误的。我必须为 curl 创建一个 cookie jar 以遍历多个重定向并且不会丢失域的 cookie。
      【解决方案3】:

      你不能。

      如果您 curl 请求,您将需要解析输出,并替换所有链接,以便它们通过您的服务器。

        www.yourdomain.com/f?=www.someotherdomain.com/realpage
      

      唯一可行的方法是在 curl 请求中使用持久性 cookie。 CURL 可以自己保存 cookie。将会话 ID 分配给 cookie 文件(在 curl 中),以便后续请求获得相同的 cookie。当用户点击链接时,您需要再次 curl 请求。

      允许site1 为site2 设置cookie 是一个安全问题。想象一下,如果您可以在浏览器中为 paypal 设置 cookie,并诱使用户认为他们已登录 int 或其他恶意操作。

      【讨论】:

      • 看来我应该找到一个更标准的解决方案,比如自动重定向之类的。谢谢
      【解决方案4】:

      事实上,这是可能的。您只需获取浏览器的 cookie 并将其作为参数传递给 curl 以模仿浏览器。 这就像一个会话劫持......

      这是一个示例代码:

      // Init curl connection
      $curl = curl_init('http://otherserver.com/');
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
      // You can add your GET or POST param
      
      // Retrieving session ID 
      $strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';    
      
      // We pass the sessionid of the browser within the curl request
      curl_setopt( $curl, CURLOPT_COOKIE, $strCookie ); 
      
      // We receive the answer as if we were the browser
      $curl_response = curl_exec($curl);
      

      如果您的目的是调用另一个网站,它工作得很好,但是如果您调用您的网络服务器(与启动 curl 命令相同),这将失败。这是因为您的会话文件仍被此脚本打开/锁定,因此您调用的 URL 无法访问它。

      如果您想绕过该限制(调用同一服务器上的页面),则必须在执行 curl 之前使用此代码关闭会话文件:

      $curl = curl_init('http://sameserver.com/');
      //...
      session_write_close();
      $curl_response = curl_exec($curl);
      

      希望这会对某人有所帮助:)

      【讨论】:

      • session_write_close();效果很好!我想给成千上万的赞成票!我疯了,不明白为什么服务器在超时之前不返回数据和响应代码。你解释得很好,效果很好。
      【解决方案5】:

      这就是我将所有浏览器 cookie 转发到 curl 并将 curl 请求的所有 cookie 返回到浏览器的方式。为此,我需要解决一些问题,例如从 curl 获取 cookie、解析 http 标头、发送多个 cookie 和会话锁定:

      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      
      // get http header for cookies
      curl_setopt($ch, CURLOPT_VERBOSE, 1);
      curl_setopt($ch, CURLOPT_HEADER, 1);
      
      // forward current cookies to curl
      $cookies = array();
      foreach ($_COOKIE as $key => $value)
      {
          if ($key != 'Array')
          {
              $cookies[] = $key . '=' . $value;
          }
      }
      curl_setopt( $ch, CURLOPT_COOKIE, implode(';', $cookies) );
      
      // Stop session so curl can use the same session without conflicts
      session_write_close();
      
      $response = curl_exec($ch);
      curl_close($ch);
      
      // Session restart
      session_start();
      
      // Seperate header and body
      list($header, $body) = explode("\r\n\r\n", $response, 2);
      
      // extract cookies form curl and forward them to browser
      preg_match_all('/^(Set-Cookie:\s*[^\n]*)$/mi', $header, $cookies);
      foreach($cookies[0] AS $cookie)
      {
           header($cookie, false);
      }
      
      echo $body;
      

      【讨论】:

      • 您可能还想添加: curl_setopt($ch,CURLOPT_USERAGENT, $_SERVER ['HTTP_USER_AGENT']);
      【解决方案6】:

      PiTheNumber 的回答很棒,但我遇到了一些问题,导致它仍将页眉打印到页面上。所以我调整它以使用更可靠的curl_getinfo函数。此版本也遵循重定向。

      public function get_page_content( $url ) {
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
          curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
          curl_setopt($ch, CURLOPT_HEADER, 1);
      
          // Forward current cookies to curl
          $cookies = array();
          foreach ($_COOKIE as $key => $value) {
              if ($key != 'Array') {
                  $cookies[] = $key . '=' . $value;
              }
          }
          curl_setopt( $ch, CURLOPT_COOKIE, implode(';', $cookies) );
      
          $destination = $url;
      
          while ($destination) {
              session_write_close();
              curl_setopt($ch, CURLOPT_URL, $destination);
              $response = curl_exec($ch);
              $curl_info = curl_getinfo($ch);
              $destination = $curl_info["redirect_url"];
              session_start();
          }
          curl_close($ch);
      
          $headers = substr($response, 0, $curl_info["header_size"]);
          $body = substr($response, $curl_info["header_size"]);
      
          // Extract cookies from curl and forward them to browser
          preg_match_all('/^(Set-Cookie:\s*[^\n]*)$/mi', $headers, $cookies);
          foreach($cookies[0] AS $cookie) {
              header($cookie, false);
          }
      
          return $body;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-23
        • 1970-01-01
        • 2017-08-11
        • 1970-01-01
        • 2016-01-11
        • 2019-09-22
        • 2012-02-02
        • 1970-01-01
        相关资源
        最近更新 更多