How to login in with Curl and SSL and cookies

Here is a working example I created from your code. This uses a function getFormFields that I wrote for a similar question (first reference at the bottom of this post) which logs into the Android market.

I think there may have been a couple of things in your script that were preventing the login from working. First, you should urlencode the URL parameters such as email and password in the post string (cURL will not do this for you). Second, I think the x value used as part of the login URL may be required.

Here is a solution that logs in successfully. Note, I re-used the original cURL handle. This is not necessary, but if you specify keep-alive, it will actually re-use the same connection, and it also saves you from having to specify the same options over and over.

Once you have the cookies, you can create a new cURL object and specify the COOKIEFILE and COOKIEJAR and you will be logged in without performing the first steps.

<?php

// options
$EMAIL            = '[email protected]';
$PASSWORD         = 'yourpassword';
$cookie_file_path = "/tmp/cookies.txt";
$LOGINURL         = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 
$agent            = "Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)";


// begin script
$ch = curl_init(); 

// extra headers
$headers[] = "Accept: */*";
$headers[] = "Connection: Keep-Alive";

// basic curl options for all requests
curl_setopt($ch, CURLOPT_HTTPHEADER,  $headers);
curl_setopt($ch, CURLOPT_HEADER,  0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);         
curl_setopt($ch, CURLOPT_USERAGENT, $agent); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); 
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); 

// set first URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL);

// execute session to get cookies and required form inputs
$content = curl_exec($ch); 

// grab the hidden inputs from the form required to login
$fields = getFormFields($content);
$fields['emailAddress'] = $EMAIL;
$fields['acctPassword'] = $PASSWORD;

// get x value that is used in the login url
$x = '';
if (preg_match('/op\.asp\?x=(\d+)/i', $content, $match)) {
    $x = $match[1];
}

//$LOGINURL   = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn";
  $LOGINURL   = "https://cart2.barnesandnoble.com/mobileacct/op.asp?x=$x";

// set postfields using what we extracted from the form
$POSTFIELDS = http_build_query($fields); 

// change URL to login URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL); 

// set post options
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS); 

// perform login
$result = curl_exec($ch);  

print $result; 


function getFormFields($data)
{
    if (preg_match('/(<form action="op.*?<\/form>)/is', $data, $matches)) {
        $inputs = getInputs($matches[1]);

        return $inputs;
    } else {
        die('didnt find login form');
    }
}

function getInputs($form)
{
    $inputs = array();

    $elements = preg_match_all('/(<input[^>]+>)/is', $form, $matches);

    if ($elements > 0) {
        for($i = 0; $i < $elements; $i++) {
            $el = preg_replace('/\s{2,}/', ' ', $matches[1][$i]);

            if (preg_match('/name=(?:["\'])?([^"\'\s]*)/i', $el, $name)) {
                $name  = $name[1];
                $value="";

                if (preg_match('/value=(?:["\'])?([^"\'\s]*)/i', $el, $value)) {
                    $value = $value[1];
                }

                $inputs[$name] = $value;
            }
        }
    }

    return $inputs;
}

This worked for me, hope that helps get you going.

Here are some other cURL answer I have that may help learn:

Leave a Comment