How to let Curl use same cookie as the browser from PHP

前端 未结 6 1048
太阳男子
太阳男子 2020-12-14 11:02

I have a PHP script that does an HTTP request on behalf of the browser and the outputs the response to the browser. Problem is when I click the links from the browser on thi

相关标签:
6条回答
  • 2020-12-14 11:31

    The Cookie is usually sent with the HTTP request header like

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

    So I guess that just have to modify the cookie part in your header.

    0 讨论(0)
  • 2020-12-14 11:35

    In fact, it is possible. You just have to take the cookie ofthe browser and pass it as a parameter to curl to mimik the browser. It's like a session jacking...

    Here is a sample code:

    // 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);
    

    It works very well if your purpose is to call another website, but this will fail if you call your web server (the same that is launching the curl command). It's because your session file is still open/locked by this script so the URL you are calling can't access it.

    If you want to bypass that restriction (call a page on the same server), you have to close the session file with this code before you execute the curl :

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

    Hope this will help someone :)

    0 讨论(0)
  • 2020-12-14 11:35

    PiTheNumber's answer was great but I ran into some issues with it that caused it to still print the headers to the page. So I adjusted it to use the more reliable curl_getinfo function. This version also follows redirects.

    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;
    }
    
    0 讨论(0)
  • 2020-12-14 11:39

    From curl_setopt:

    By default, libcurl always stores and loads all cookies, independent if they are session cookies or not.

    However you may need to set cookies directly, which can be done using:

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

    Which is the same as the Set-Cookie HTTP header. Check you're not using curl_setopt($ch, CURLOPT_COOKIESESSION, true) as this will make libcurl ignore some cookies.

    0 讨论(0)
  • 2020-12-14 11:39

    You can't.

    If you curl the request, you will need to parse the output, and replace all links so they go thru your server.

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

    The only way this would work is if you use persistent cookies in your curl request. CURL can keep cookies itself. Assign a session ID to the cookie file (in curl) so subsequent requests get the same cookies. When a user clicks a link, you will need to curl the request again.

    It is a security issue to allow site1 to set cookies for site2. Imagine if you could set cookies in the browser for paypal and trick the user into thinking they had logged int or some other malicious action.

    0 讨论(0)
  • 2020-12-14 11:55

    This is how I forward all browser cookies to curl and also return all cookies for the curl request back to the browser. For this I needed to solve some problems like getting cookies from curl, parsing http header, sending multiple cookies and session locking:

    $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;
    
    0 讨论(0)
提交回复
热议问题