Как разрешить Curl использовать тот же cookie, что и браузер из PHP - PullRequest
10 голосов
/ 13 июля 2009

У меня есть PHP-скрипт, который выполняет HTTP-запрос от имени браузера и выводит ответ в браузер. Проблема в том, что когда я нажимаю на ссылки из браузера на этой странице, он жалуется на переменные cookie. Я предполагаю, что ему нужны файлы cookie браузера для сайта.

как я могу перехватить и переслать его на удаленный сайт?

Ответы [ 6 ]

10 голосов
/ 28 мая 2014

Таким образом я пересылаю все файлы cookie браузера для скручивания, а также возвращаю все файлы cookie для запроса скручивания обратно в браузер. Для этого мне нужно было решить некоторые проблемы, такие как получение файлов cookie от curl, парсинг заголовка 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;
5 голосов
/ 14 сентября 2013

На самом деле это возможно. Вам просто нужно взять cookie браузера и передать его в качестве параметра, чтобы свернуться, чтобы имитировать браузер. Это похоже на сеанс джека ...

Вот пример кода:

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

Надеюсь, это кому-нибудь поможет:)

3 голосов
/ 13 июля 2009

С curl_setopt:

По умолчанию libcurl всегда сохраняет и загружает все куки, независимо от того, являются ли они сессионными куки или нет.

Однако вам может потребоваться установить файлы cookie напрямую, что можно сделать с помощью:

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

Что совпадает с HTTP-заголовком Set-Cookie. Убедитесь, что вы не используете curl_setopt($ch, CURLOPT_COOKIESESSION, true), так как это заставит libcurl игнорировать некоторые куки.

1 голос
/ 13 июля 2009

Вы не можете.

Если вы свернете запрос, вам нужно будет проанализировать выходные данные и заменить все ссылки, чтобы они проходили через ваш сервер.

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

Единственный способ, которым это будет работать, - это использовать постоянные файлы cookie в своем запросе керлинга. CURL может хранить куки сам. Присвойте идентификатор сеанса файлу cookie (в curl), чтобы последующие запросы получали те же файлы cookie. Когда пользователь нажимает на ссылку, вам необходимо снова свернуть запрос.

Это проблема безопасности, позволяющая сайту1 устанавливать файлы cookie для сайта2. Представьте, что вы можете установить куки в браузере для PayPal и заставить пользователей думать, что они вошли в систему int или в какое-либо другое вредоносное действие.

0 голосов
/ 21 июля 2016

Ответ 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;
}
0 голосов
/ 13 июля 2009

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 в вашем заголовке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...