Kniganapolke Tech Blog

Form authorization with curl, php

Posted on: October 8, 2009

I had to make a php based site interchange some information with a MS Sharepoint based site, moreover the latter was secured by a proxy-server and used SSL (https).

The first step was to pass authorization on proxy-server, which was supposed to be done through a special authorization form.
Using Firebug add-on for Firefox (or Fiddler for FF and IE) I watched the POST request headers and fields sent when submitting authorization form manually.

So I needed to make the same POST request with credentials from php script.

Moreover, a cookie was set after authorization (either fault or successfull) which we need to store and use for following requests.
This can be done with curl (libcurl library for php).

$ch = curl_init();
// $authorization_url - URL what to post credentials to, for example "https://myhost/login"
curl_setopt($ch, CURLOPT_URL, $authorization_url);

curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt ($ch, CURLOPT_REFERER, 'set your referer here');

// Do not follow "Location:" header
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

// To use SSL protocol without verifying or providing any certificates
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Avoid "Expect: 100-continue" header
curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Expect:'));

// Indicate it's a POST request
curl_setopt ($ch, CURLOPT_POST, 1);

// Prepare POST fields
$postfields  = 'Field1='.urlencode('field 1 value');
$postfields .= '&Field2='.urlencode('field 2 value');
$postfields .= '&Field3='.urlencode('field 3 value');
curl_setopt ($ch, CURLOPT_POSTFIELDS, $postfields);

// For debugging purposes
// return transfer data as a result
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// read headers
curl_setopt($ch, CURLOPT_HEADER, 1);
// show request headers, will display all the outgoing info, including fields
curl_setopt($ch, CURLINFO_HEADER_OUT, true);

// Make the request
$data = curl_exec($ch);
$errors = curl_error($ch)
// get info about the transfer, for debugging purposes
$details = curl_getinfo($ch); 

curl_close($ch);

// Displaying debugging info
//var_dump($data);
//var_dump($errors);
//var_dump($details);

// Parse data for cookie header, store cookie as it will be used for subsequent requests
$cookie = '';
$pattern = '/Set-Cookie:(.*?)\n/';
if (preg_match($pattern, $data, $result))
$cookie = $result[1];

Setting “CURLINFO_HEADER_OUT” option to true seems to be the only way to see the outgoing request headers and POST data.

Then we can make a GET request to ask for a resource (a page, for example). Send authorization cookie using “CURLOPT_COOKIE” option.

$ch = curl_init();
// Set URL of the target resource (for example, https://myserver/targetresource)
curl_setopt($ch, CURLOPT_URL, $resource_url);

curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt ($ch, CURLOPT_REFERER, 'set your referer here');

// Do not follow "Location:" header
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Expect:'));

// Set authorization cookie that we got as a result of our first request
curl_setopt($ch, CURLOPT_COOKIE, $cookie);

// For debugging purposes
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);

$data = curl_exec($ch);
$errors = curl_error($ch)
// get info about the transfer, for debugging purposes
$details = curl_getinfo($ch);

// Displaying debugging info
//var_dump($data);
//var_dump($errors);
//var_dump($details);

curl_close($ch);

Links that helped:

Advertisements

6 Responses to "Form authorization with curl, php"

This work if all your cookies are set on one line. But in my case I had cookies set on multiple lines so this worked to retrieve all cookies:

$pattern = ‘/Set-Cookie:(.*?)\n/’;
if (preg_match_all($pattern, $data, $result))
$cookie = implode(‘;’, $result[1]);

Thanks, your code seems to be more generic.

Hi, I have been trying something similar but I keep getting Bad Request error when I try to follow this approach.

Do you have any solution for that?

I suggest you to debug and look into your request HTTP headers. Are you geting 400 at the first request or at the second one?

You save my life!!!

I have been dealing with this for a whole week! When I was about to commit a suicide, you showed up and saved my life!!!

Thank you so freaking muchhhhhhhhh for this!

Happy to hear that )))

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


  • None
  • kniganapolke: Happy to hear that )))
  • Khuong: You save my life!!! I have been dealing with this for a whole week! When I was about to commit a suicide, you showed up and saved my life!!! Tha
  • kniganapolke: Thanks, your code seems to be more generic.

Categories

%d bloggers like this: