How to login in with Curl and SSL and cookies

32,554

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:

Share:
32,554
Heather McVay
Author by

Heather McVay

surf

Updated on July 09, 2022

Comments

  • Heather McVay
    Heather McVay almost 2 years

    I been trying to log into barnesandnoble.com mobile site with curl and have had no luck so far. I get back the page with no errors and it defaults my email into the email input form box of the login page again (in the form returned from print $result).

    The same code can actually let me go into ebay correctly by changing the LOGINURL to point to ebay's login

    The only difference being that barnesandnobles is https:// and ebay login was http://

    Also, I believe that barnes website is asp/aspx so I don't know how that would handle cookies and _state differently

    Any help would be appreciated as I been trying to debug this for the past 16hrs

    also, my cookie.txt is writable and working

    <?php
        $cookie_file_path = "C:/test/cookie.txt";
        $LOGINURL = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 
        $agent = "Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)";
    
        $ch = curl_init(); 
    
        $headers[] = "Accept: */*";
        $headers[] = "Connection: Keep-Alive";
        $headers[] = "Content-type: application/x-www-form-urlencoded;charset=UTF-8";
    
        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_URL, $LOGINURL);
        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);
    
        $content = curl_exec($ch); 
    
        curl_close($ch); 
    
        unset($ch); 
    
        // NAME="path_state" value="6657403">
    
        if(stristr($content,"path_state")){
            $array1 = explode('path_state" value="',$content);
            $content1 = $array1[1];
            $array2 = explode('">',$content1);
            $content2 = $array2[0];
        }
    
        $LOGINURL = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn";
        $POSTFIELDS = "d_hidPageStamp=V_3_17&hidViewMode=opSignIn&stage=signIn&previousStage=mainStage&path_state=" .  $content2 . "&[email protected]&acctPassword=YOURPASSWORD";
        $reffer = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 
    
        $ch = curl_init(); 
    
        $headers[] = "Accept: */*";
        $headers[] = "Connection: Keep-Alive";
        $headers[] = "Content-type: application/x-www-form-urlencoded;charset=UTF-8";
    
        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_URL, $LOGINURL); 
        curl_setopt($ch, CURLOPT_USERAGENT, $agent); 
        curl_setopt($ch, CURLOPT_POST, 1); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
        curl_setopt($ch, CURLOPT_REFERER, $reffer); 
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); 
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); 
    
        $result = curl_exec($ch);  
    
        print $result; 
    ?>