PHP Curl - Cookies Problem

PHP Curl - Cookies problem

EDIT: This code is broken as of June 2016. See this answer for explanation and potential workaround. The same technology mentioned in the previous link was added to associates' login.


I wrote this code up and it works well for me, in the last var_dump I see all my account info and things like that. If you don't delete the cookies, you can make subsequent curl requests to protected pages with your login.

Hopefully this can help you learn about how to do it. A lot of times on big sites you need to visit the login page to get cookies set, and also they usually have csrf tokens on the forms you need to submit with them.

Of course if amazon changes their forms or url's around a bit, this will have to be adapted some, but hopefully they don't do that too often.

<?php

$email = 'you@yoursite.com';
$password = 'password';

// initial login page which redirects to correct sign in page, sets some cookies
$URL = 'https://affiliate-program.amazon.com/gp/associates/join/landing/main.html';

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $URL);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'amazoncookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'amazoncookie.txt');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
//curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, fopen('php://stdout', 'w'));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

$page = curl_exec($ch);

//var_dump($page);exit;

// try to find the actual login form
if (!preg_match('/<form name="sign_in".*?<\/form>/is', $page, $form)) {
die('Failed to find log in form!');
}

$form = $form[0];

// find the action of the login form
if (!preg_match('/action=(?:\'|")?([^\s\'">]+)/i', $form, $action)) {
die('Failed to find login form url');
}

$URL2 = $action[1]; // this is our new post url

// find all hidden fields which we need to send with our login, this includes security tokens
$count = preg_match_all('/<input type="hidden"\s*name="([^"]*)"\s*value="([^"]*)"/i', $form, $hiddenFields);

$postFields = array();

// turn the hidden fields into an array
for ($i = 0; $i < $count; ++$i) {
$postFields[$hiddenFields[1][$i]] = $hiddenFields[2][$i];
}

// add our login values
$postFields['username'] = $email;
$postFields['password'] = $password;

$post = '';

// convert to string, this won't work as an array, form will not accept multipart/form-data, only application/x-www-form-urlencoded
foreach($postFields as $key => $value) {
$post .= $key . '=' . urlencode($value) . '&';
}

$post = substr($post, 0, -1);

// set additional curl options using our previous options
curl_setopt($ch, CURLOPT_URL, $URL2);
curl_setopt($ch, CURLOPT_REFERER, $URL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

$page = curl_exec($ch); // make request

var_dump($page); // should be logged in

cURL returns please enable cookies?

Well their cloudflare system was just blocking the IP of my server (it was a shared one), getting a new host with its own IP solved the issue...
Thank you for your time guys, appreciated it.

Why php curl does not save cookie in my cookiefile?

When setting CURLOPT_COOKIEJAR, you need to use an absolute path. You can do this easily by using:

curl_setopt ($ch, CURLOPT_COOKIEJAR, realpath($cookie_file) );

Reference: cannot use cookies in cURL PHP

PHP cURL cookie not saved after curl_close

According to the manual entry for curl_close:

This function has no effect. Prior to PHP 8.0.0, this function was used to close the resource.

This reason is explained in this article :

From PHP 8 and forward, curl_init function returns an instance of \CurlHandle class

Because the handlers are now objects, the resources will be destroyed during garbage collection, unless the handler is explicitly closed with an unset() call.

To release the cookie file resource you need to unset the curl handle :

unset($ch);

Getting and setting Cookies in PHP Curl Serverside

Curl manages cookies autonomously, you don't need to parse and set them:

<?php 
$ch = curl_init('https://www.test.com/getcookie');

$cookiesFile = "cookies.txt"; // <--- cookies are stored here

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, false); // <---

curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiesFile ); // <---
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiesFile ); // <---

$result = curl_exec($ch);

curl_close($ch);

if( $result === false ) {
// failure
}

Then

<?php

$cookiesFile = "cookies.txt"; // <--- cookies are retrieved here

$curl = curl_init( 'https://test.com/api' );
curl_setopt( $curl, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer ' . $token ) );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1);

curl_setopt( $curl, CURLOPT_COOKIEFILE, $cookiesFile ); // <---
curl_setopt( $curl, CURLOPT_COOKIEJAR, $cookiesFile ); // <---

$getbalance = curl_exec( $curl );
curl_close($curl);

You can specify a file where curl stores and reads cookies as in the example above.

Upon subsequent curl calls the cookies file is updated.

The cookies file doesn't need to exist prior of first call but of course PHP must have read/write access.



Related Topics



Leave a reply



Submit