I have some problem with PHP Curl and cookies authentication.
I have a file Connector.php which authenticates users on another server and returns the cookie of the current user.
The Problem is that I want to authenticate thousands of users with curl but it authenticates and saves COOKIES only for one user at a time.
The code for connector.php is this:
<?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); ?>
Here is the process of authentication:
Connector.php?service=logon&user_name=user32&user_pass=123
Connector.php?service=logosessionInfo
returns info about the user based on the cookies saved earlier with logon service.The problem is that this code saves the cookie in one file for each user and can't handle multiple user authentications.
You can't. The only way this would work is if you use persistent cookies in your curl request. CURL can keep cookies itself. Assign a session ID to the cookie file (in curl) so subsequent requests get the same cookies.
curl has a full cookie "engine" built in. If you just activate it, you can have curl receive and send cookies exactly as mandated in the specs. tell curl a file to read cookies from and start the cookie engine, or if it is not a file it will pass on the given string.
Cookies are passed to Curl with the --cookie "Name=Value" command line parameter. Curl automatically converts the given parameter into the Cookie: Name=Value request header. Cookies can be sent by any HTTP method, including GET, POST, PUT, and DELETE, and with any data, including JSON, web forms, and file uploads.
Uses of cURL in PHPcURL is a PHP extension that allows you to use the URL syntax to receive and submit data. cURL makes it simple to connect between various websites and domains. Obtaining a copy of a website's material. Submission of forms automatically, authentication and cookie use.
You can specify the cookie file with a curl opt. You could use a unique file for each user.
curl_setopt( $curl_handle, CURLOPT_COOKIESESSION, true ); curl_setopt( $curl_handle, CURLOPT_COOKIEJAR, uniquefilename ); curl_setopt( $curl_handle, CURLOPT_COOKIEFILE, uniquefilename );
The best way to handle it would be to stick your request logic into a curl function and just pass the unique file name in as a parameter.
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; }
I use this for quick grabs. It takes the url and an array of options.
In working with a similar problem I created the following function after combining a lot of resources I ran into on the web, and adding my own cookie handling. Hopefully this is useful to someone else.
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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With