2009-07-13 4 views
9

J'ai un script PHP qui fait une requête HTTP au nom du navigateur et les sorties de la réponse au navigateur. Le problème est quand je clique sur les liens du navigateur sur cette page il se plaint des variables de cookie. Je suppose qu'il a besoin du cookie (s) des navigateurs pour le site. Comment puis-je l'intercepter et le transférer vers le site distant?Comment faire pour utiliser Curl cookie même que le navigateur de PHP

Répondre

2

Vous ne pouvez pas.

Si vous bouclez la requête, vous devrez analyser la sortie et remplacer tous les liens pour qu'ils passent par votre serveur. La seule façon dont cela fonctionnerait est si vous utilisez des cookies persistants dans votre demande curl. CURL peut conserver les cookies lui-même. Attribuez un ID de session au fichier cookie (en boucle) afin que les demandes suivantes obtiennent les mêmes cookies. Lorsqu'un utilisateur clique sur un lien, vous devrez recopier la requête.

Il s'agit d'un problème de sécurité pour permettre à site1 de définir des cookies pour site2. Imaginez si vous pouviez mettre des cookies dans le navigateur pour paypal et faire croire à l'utilisateur qu'il avait ouvert une session int ou une autre action malveillante.

+0

Il semble que je devrais trouver une solution plus standard comme la redirection automatique ou quelque chose. Merci –

0

Le Cookie est généralement envoyé avec l'en-tête de requête HTTP comme

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

Donc je suppose que suffit de modifier la partie cookie dans votre tête.

3

De curl_setopt:

Par défaut, libcurl enregistre et charge toujours tous les cookies, les cookies indépendants si elles sont de session ou non.

Cependant, vous devrez peut-être définir des cookies directement, ce qui peut être fait en utilisant:

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

Ce qui est le même que l'en-tête HTTP Set-Cookie. Vérifiez que vous n'utilisez pas curl_setopt($ch, CURLOPT_COOKIESESSION, true), car cela libèrera libcurl de certains cookies.

+0

J'ai récemment découvert que le commentaire "Par défaut, libcurl stocke toujours et charge tous les cookies" semble être faux depuis PHP 5.3.8. J'ai dû créer un cookie jar pour que curl traverse plus d'une redirection et ne pas perdre les cookies pour le domaine. –

5

En fait, c'est possible. Il suffit de prendre le cookie du navigateur et de le passer en paramètre pour boucler le navigateur. Il est comme une jacking session ...

Voici un exemple de 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); 

Il fonctionne très bien si votre but est d'appeler un autre site, mais cela échouera si vous appelez votre serveur web (le même qui lance la commande curl). C'est parce que votre fichier de session est toujours ouvert/verrouillé par ce script, donc l'URL que vous appelez ne peut pas y accéder.

Si vous voulez contourner cette restriction (appel d'une page sur le même serveur), vous devez fermer le fichier de session avec ce code avant d'exécuter la boucle:

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

Espérons que cela aidera quelqu'un:

+0

session_write_close(); fonctionne très bien! Je voulais donner des milliers de upvote! J'étais folle de ne pas comprendre pourquoi le serveur ne renvoie aucune donnée et aucun code de réponse jusqu'à l'expiration. Vous avez très bien expliqué et cela fonctionne bien. – Tarik

10

C'est ainsi que je redirige tous les cookies du navigateur pour boucler et également renvoyer tous les cookies pour la demande de curl retour au navigateur.Pour cela, je devais résoudre certains problèmes comme obtenir les cookies de boucle, l'analyse syntaxique en-tête HTTP, envoyer plusieurs cookies et verrouillage de la session:

$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; 
+1

Vous pouvez également ajouter: curl_setopt ($ ch, CURLOPT_USERAGENT, $ _SERVER ['HTTP_USER_AGENT']); –

0

réponse de PiTheNumber était super mais j'ai rencontré quelques problèmes avec ce qui l'a fait encore imprimer les en-têtes à la page. Je l'ai donc ajusté pour utiliser la fonction curl_getinfo plus fiable. Cette version suit également les redirections.

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; 
} 
Questions connexes