PHP Curl И Файлы Cookie


У меня некоторые проблемы с аутентификацией PHP Curl и Cookies.

У меня есть файл Connector.php , который аутентифицирует пользователей на другом сервере и возвращает файл cookie с текущим пользователем.

Проблема в том, что я хочу аутентифицировать тысячи пользователей с помощью curl, но он аутентифицирует и сохраняет файлы COOKIE только для одного пользователя за раз.

Код для connector.php это:

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

Вот процесс аутентификации:

  1. Пользователь вводит имя пользователя и пароль: Connector.php?service=вход в систему и имя пользователя=user32 и user_pass=123
  2. Connector.php?service=logosessioninfo возвращает информацию о пользователе на основе файлов cookie, сохраненных ранее с помощью службы входа в систему.

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

Author: Kenster, 2012-10-14

6 answers

Вы можете указать файл cookie с помощью опции curl. Вы можете использовать уникальный файл для каждого пользователя.

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

Лучший способ справиться с этим - вставить логику запроса в функцию curl и просто передать уникальное имя файла в качестве параметра.

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

Я использую это для быстрого захвата. Он принимает URL-адрес и множество параметров.

 24
Author: Adam, 2012-10-14 19:19:46

Работая с аналогичной проблемой, я создал следующую функцию после объединения множества ресурсов, с которыми я столкнулся в Интернете, и добавления собственной обработки файлов cookie. Надеюсь, это пригодится кому-то еще.

      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;
}
 20
Author: Doug, 2017-12-01 14:21:43

Сначала создайте временный файл cookie с помощью функции tempnam():

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

Чем выполнить curl init, файл cookie ведьмы сохраняется как временный файл:

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

Или посетите данные cookie, где хранятся временные данные:

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

Это загрузит страницу инициализации файлов cookie:

curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
 11
Author: Marin Sagovac, 2012-10-14 19:16:52

Здесь вы можете найти некоторую полезную информацию о cURL & cookies http://docstore.mik.ua/orelly/webprog/pcook/ch11_04.htm .

Вы также можете использовать этот хорошо выполненный метод https://github.com/alixaxel/phunction/blob/master/phunction/Net.php#L89 как функция:

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

И передайте это как параметр $cookie:

$cookie_jar = tempnam('/tmp','cookie');
 2
Author: ewake, 2015-05-17 17:44:58

Вы можете определить разные файлы cookie для каждого пользователя с помощью CURLOPT_COOKIEFILE и CURLOPT_COOKIEJAR. Создайте разные файлы для каждого пользователя, чтобы у каждого был свой собственный сеанс на основе файлов cookie на удаленном сервере.

 1
Author: s.webbandit, 2012-10-14 19:12:22

Решения, описанные выше, даже с уникальными именами файлов cookie, могут вызвать множество проблем в масштабе.

Нам пришлось выполнить множество проверок подлинности с помощью этого решения, и наш сервер вышел из строя из-за большого количества операций чтения и записи файлов.

Решением для этого было использовать обратный прокси-сервер Apache и вообще пропускать запросы CURL.

Подробную информацию о том, как использовать прокси-сервер на Apache, можно найти здесь: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html

 0
Author: Shark, 2017-06-26 06:52:39