Как заставить Curl использовать тот же файл cookie, что и браузер с PHP

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

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

Solutions Collecting From Web of "Как заставить Curl использовать тот же файл cookie, что и браузер с PHP"

Вы не можете.

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

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

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

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

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

На самом деле это возможно. Вам просто нужно взять 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_init('http://sameserver.com/'); //... session_write_close(); $curl_response = curl_exec($curl); 

Надеюсь, это поможет кому-то 🙂

От curl_setopt :

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

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

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

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

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

Ответ 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; }