web-dev-qa-db-fra.com

PHP Curl Et Cookies

J'ai un problème avec l'authentification PHP Curl and Cookies.

J'ai un fichier Connector.php qui authentifie les utilisateurs sur un autre serveur et renvoie le cookie avec l'utilisateur actuel.

Le problème est que je veux authentifier des milliers d’utilisateurs avec curl mais cela authentifie et enregistre les biscuits pour un seul utilisateur à la fois.

le code de connector.php est le suivant:

    <?php
    if(!count($_REQUEST)) {
        die("No Access!");
    }


    //Core Url For Services
    define ('ServiceCore', 'http://example.com/core/');


    //Which Internal Service Should Be Called
    $path = $_GET['service'];


    //Service To Be Queried
    $url = ServiceCore.$path;

    //Open the Curl session
    $session = curl_init($url);

    // If it's a GET, put the GET data in the body
    if ($_GET['service']) {
        //Iterate Over GET Vars
        $postvars = '';
        foreach($_GET as $key=>$val) {
            if($key!='service') {
                $postvars.="$key=$val&";
            }
        }
        curl_setopt ($session, CURLOPT_POST, true);
        curl_setopt ($session, CURLOPT_POSTFIELDS, $postvars);
    }


    //Create And Save Cookies
    $tmpfname = dirname(__FILE__).'/cookie.txt';
    curl_setopt($session, CURLOPT_COOKIEJAR, $tmpfname);
    curl_setopt($session, CURLOPT_COOKIEFILE, $tmpfname);

    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);

    // EXECUTE
    $json = curl_exec($session);
        echo $json;
    curl_close($session);
?>

Voici le processus d'authentification:

  1. L'utilisateur entre le nom d'utilisateur et le mot de passe: Connector.php? Service = logon & user_name = user32 & user_pass = 123  
  2. Connector.php? Service = logosessionInfo ceci renvoie des informations sur l'utilisateur basées sur les cookies enregistrés précédemment avec le service de connexion.

Le problème est que ce code enregistre Cookie dans un fichier pour un utilisateur et ne peut pas gérer l'authentification de plusieurs utilisateurs.

27
Shark

Les solutions décrites ci-dessus, même avec des noms uniques CookieFile, peuvent poser de nombreux problèmes à grande échelle.

Avec cette solution, nous avons dû effectuer de nombreuses authentifications et notre serveur est tombé en panne en raison d'actions de lecture/écriture élevées.

La solution pour cela consistait à utiliser Apache Reverse Proxy et à omettre les requêtes CURL.

Vous trouverez des informations détaillées sur l’utilisation du proxy sur Apache à l’adresse suivante: https://httpd.Apache.org/docs/2.4/howto/reverse_proxy.html

0
Shark

Vous pouvez spécifier le fichier de cookie avec un curl opt. Vous pouvez utiliser un fichier unique pour chaque utilisateur.

curl_setopt( $curl_handle, CURLOPT_COOKIESESSION, true );
curl_setopt( $curl_handle, CURLOPT_COOKIEJAR, uniquefilename );
curl_setopt( $curl_handle, CURLOPT_COOKIEFILE, uniquefilename );

La meilleure façon de le gérer serait de coller votre logique de requête dans une fonction curl et de simplement passer le nom de fichier unique en paramètre.

    function fetch( $url, $z=null ) {
            $ch =  curl_init();

            $useragent = isset($z['useragent']) ? $z['useragent'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2';

            curl_setopt( $ch, CURLOPT_URL, $url );
            curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
            curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
            curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
            curl_setopt( $ch, CURLOPT_POST, isset($z['post']) );

            if( isset($z['post']) )         curl_setopt( $ch, CURLOPT_POSTFIELDS, $z['post'] );
            if( isset($z['refer']) )        curl_setopt( $ch, CURLOPT_REFERER, $z['refer'] );

            curl_setopt( $ch, CURLOPT_USERAGENT, $useragent );
            curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, ( isset($z['timeout']) ? $z['timeout'] : 5 ) );
            curl_setopt( $ch, CURLOPT_COOKIEJAR,  $z['cookiefile'] );
            curl_setopt( $ch, CURLOPT_COOKIEFILE, $z['cookiefile'] );

            $result = curl_exec( $ch );
            curl_close( $ch );
            return $result;
    }

Je l'utilise pour des prises rapides. Il faut l'URL et un tableau d'options.

24
Adam

En travaillant avec un problème similaire, j'ai créé la fonction suivante après avoir combiné beaucoup de ressources rencontrées sur le Web et ajouté ma propre gestion des cookies. Espérons que cela soit utile à quelqu'un d'autre.

      function get_web_page( $url, $cookiesIn = '' ){
        $options = array(
            CURLOPT_RETURNTRANSFER => true,     // return web page
            CURLOPT_HEADER         => true,     //return headers in addition to content
            CURLOPT_FOLLOWLOCATION => true,     // follow redirects
            CURLOPT_ENCODING       => "",       // handle all encodings
            CURLOPT_AUTOREFERER    => true,     // set referer on redirect
            CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
            CURLOPT_TIMEOUT        => 120,      // timeout on response
            CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
            CURLINFO_HEADER_OUT    => true,
            CURLOPT_SSL_VERIFYPEER => true,     // Validate SSL Certificates
            CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
            CURLOPT_COOKIE         => $cookiesIn
        );

        $ch      = curl_init( $url );
        curl_setopt_array( $ch, $options );
        $rough_content = curl_exec( $ch );
        $err     = curl_errno( $ch );
        $errmsg  = curl_error( $ch );
        $header  = curl_getinfo( $ch );
        curl_close( $ch );

        $header_content = substr($rough_content, 0, $header['header_size']);
        $body_content = trim(str_replace($header_content, '', $rough_content));
        $pattern = "#Set-Cookie:\\s+(?<cookie>[^=]+=[^;]+)#m"; 
        preg_match_all($pattern, $header_content, $matches); 
        $cookiesOut = implode("; ", $matches['cookie']);

        $header['errno']   = $err;
        $header['errmsg']  = $errmsg;
        $header['headers']  = $header_content;
        $header['content'] = $body_content;
        $header['cookies'] = $cookiesOut;
    return $header;
}
21
Doug

Commencez par créer un cookie temporaire à l'aide de la fonction tempnam ():

$ckfile = tempnam ("/tmp", "CURLCOOKIE");

Ensuite, exécutez curl init. Le cookie enregistre dans un fichier temporaire:

$ch = curl_init ("http://uri.com/");
curl_setopt ($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec ($ch);

Ou visitez les données de cookie où est stocké les données temporaires:

$ch = curl_init ("http://somedomain.com/cookiepage.php");
curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec ($ch);

Cela chargera la page d'initialisation du cookie:

curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
12
Marin Sagovac

Vous trouverez ici des informations utiles sur cURL & cookies http://docstore.mik.ua/orelly/webprog/pcook/ch11_04.htm

Vous pouvez également utiliser cette méthode bien faite https://github.com/alixaxel/phunction/blob/master/phunction/Net.php#L89 comme une fonction:

function CURL($url, $data = null, $method = 'GET', $cookie = null, $options = null, $retries = 3)
{
    $result = false;

    if ((extension_loaded('curl') === true) && (is_resource($curl = curl_init()) === true))
    {
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_FAILONERROR, true);
        curl_setopt($curl, CURLOPT_AUTOREFERER, true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

        if (preg_match('~^(?:DELETE|GET|HEAD|OPTIONS|POST|PUT)$~i', $method) > 0)
        {
            if (preg_match('~^(?:HEAD|OPTIONS)$~i', $method) > 0)
            {
                curl_setopt_array($curl, array(CURLOPT_HEADER => true, CURLOPT_NOBODY => true));
            }

            else if (preg_match('~^(?:POST|PUT)$~i', $method) > 0)
            {
                if (is_array($data) === true)
                {
                    foreach (preg_grep('~^@~', $data) as $key => $value)
                    {
                        $data[$key] = sprintf('@%s', rtrim(str_replace('\\', '/', realpath(ltrim($value, '@'))), '/') . (is_dir(ltrim($value, '@')) ? '/' : ''));
                    }

                    if (count($data) != count($data, COUNT_RECURSIVE))
                    {
                        $data = http_build_query($data, '', '&');
                    }
                }

                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }

            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));

            if (isset($cookie) === true)
            {
                curl_setopt_array($curl, array_fill_keys(array(CURLOPT_COOKIEJAR, CURLOPT_COOKIEFILE), strval($cookie)));
            }

            if ((intval(ini_get('safe_mode')) == 0) && (ini_set('open_basedir', null) !== false))
            {
                curl_setopt_array($curl, array(CURLOPT_MAXREDIRS => 5, CURLOPT_FOLLOWLOCATION => true));
            }

            if (is_array($options) === true)
            {
                curl_setopt_array($curl, $options);
            }

            for ($i = 1; $i <= $retries; ++$i)
            {
                $result = curl_exec($curl);

                if (($i == $retries) || ($result !== false))
                {
                    break;
                }

                usleep(pow(2, $i - 2) * 1000000);
            }
        }

        curl_close($curl);
    }

    return $result;
}

Et passez ceci en tant que paramètre $cookie:

$cookie_jar = tempnam('/tmp','cookie');
2
ewake

Vous pouvez définir différents cookies pour chaque utilisateur avec CURLOPT_COOKIEFILE et CURLOPT_COOKIEJAR. Créez un fichier différent pour chaque utilisateur afin que chacun ait sa propre session basée sur les cookies sur un serveur distant.

1
s.webbandit