PHP Curl и печенье

У меня есть некоторые проблемы с проверкой подлинности PHP Curl и Cookies.

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

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

код для 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);
?>

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

Пользователь вводит логин и пароль:Connector.php? Сервис = вход и user_name = user32 & user_pass = 123Connector.php? Сервис = logosessionInfo возвращает информацию о пользователе на основе файлов cookie, сохраненных ранее с помощью службы входа.

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

 Shark14 окт. 2012 г., 21:36
Я решил свою проблему с созданием разных файлов cookie для разных пользователей с уникальным PHPSESSID.$tmpfname = dirname(__FILE__).'/'.$_COOKIE['PHPSESSID'].'.txt';
 Shark08 мар. 2015 г., 19:38
Нет. Если у вас много пользователей, это плохо. Это вызывает сбой сервера Apache. Я исправил эту проблему с прокси-сервером Apache. И удалил весь мой код CURL.
 trainoasis21 февр. 2014 г., 10:16
Это хорошая идея, если есть много пользователей?

Ответы на вопрос(6)

я создал следующую функцию после объединения множества ресурсов, с которыми я столкнулся в Интернете, и добавления собственной обработки файлов 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;
}
 Igor Savinkin02 янв. 2015 г., 03:52
@Doug, я проверил регулярное выражение#Set-Cookie:\\s+(?<cookie>[^=]+=[^;]+)#m вашего кода вВот и двигатель регулярных выражений объясняет эту часть\\s+ как:\` matches the character \ literallys + `буквально соответствует символу s (с учетом регистра) - не является ли это ошибкой в этой части регулярного выражения, не должно ли это быть\s+ (только один обратный слеш)?
 Doug03 янв. 2015 г., 05:11
@Igor, \\ потому что при работе со строками в PHP\ рассматривается как escape-символ, В результате вам нужно две косые черты, чтобы равняться одной косой черте в оцениваемой строке (которая затем будет использоваться для совпадения с RegEx). Вы правы с точки зрения RegEx, я хочу только одну косую черту.
 jedema25 июл. 2014 г., 15:24
Очень полезный код. Оно работает. Спасибо. Если люди хотят получить код состояния HTTP, используйте следующий синтаксис: $ header ['http_code'];
Решение Вопроса

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

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

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

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

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

После выполнения команды curl init witch 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);

Это загрузит страницу инициализации куки:

curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
 Marin Sagovac24 февр. 2014 г., 02:31
Удалите файлы cookie, если они хранятся дольше 24 часов. Сохраните данные cookie для $ ckfile отдельно для проверки всех файлов внутри / tmp.
 Wahaj Ahmed Ansari11 авг. 2017 г., 16:53
Через 3 года Вы все еще спасаете жизнь, Марин, для людей, не являющихся PHP, таких как я. После прохождения загрузки ответов stackoverflow, вот один, который хорошо объяснен упорядоченным образом.
 trainoasis21 февр. 2014 г., 10:19
Что делать, если огромное количество пользователей пытаются получить доступ к странице одновременно, и у вас уже есть некоторые файлы, например, в / tmp? Документы PHP говорят: Примечание: если PHP не может создать файл с указанным параметром dir, он возвращается к системному значению по умолчанию. В NTFS это также происходит, если указанный каталог содержит более 65534 файлов.

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

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

 trainoasis21 февр. 2014 г., 10:15
Как насчет того, когда эта страница используется большим количеством пользователей (более 10 тысяч)? Разве это не огромная нагрузка на сервер?

вать уникальный файл для каждого пользователя.

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 и массив опций.

 user323628922 июл. 2017 г., 18:21
спасибо, решил мою проблему!

Ваш ответ на вопрос