skip to Main Content

I am trying to use php curl to get the login token from an external webpage
but the login token I’m receiving is different from the actual one.

Could someone please tell me what I’m missing.

$ch = curl_init();
url_setopt($ch, CURLOPT_URL, "https://grprek.jeddahknowledgeschool.com/login/index.php");
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, "");
$answer = curl_exec($ch);
echo $answer;

if (curl_error($ch)) {
    echo curl_error($ch);
}
?>
<form  action="<?php echo $virtualLink; ?>" method="post" target="_new" id="login" >
           
    <input name="logintoken" type="hidden" value="<?php echo $vlLoginToken;?>" />
    <input style="background-color: transparent;" id="username" name="username" type="hidden" value="<?php echo $username;?>" >
    <input id="password" name="password" type="hidden" value="<?php echo $vlPassword;?>">
    <input style=" width:100px; height:100px;  margin-right:auto; margin-left:auto; display:block; border:none; background-color: transparent;" 
        src="" 
        type="image" 
        alt="turnitin" 
        title="turnitin">
</form>
</td>

2

Answers


  1. Using a fairly basic and re-usable function below to make the curl requests you would initially perform a GET request to begin the session. The initial GET request is used to discover and store the cookies used and to parse the HTML to find the logintoken from the form.

    You use DOMDocument/DOMXpath to process the HTML and find the token. That discovered token will then be used to create the POST request – ie: the login.

    function curl( $url=null, $options=null ){
        /*
            Download a copy of CACERT.pem from
            https://curl.haxx.se/docs/caextract.html
            and edit path below
        */
        $cacert='c:/wwwroot/cacert.pem';
        
        $curl=curl_init();
        if( parse_url( $url, PHP_URL_SCHEME )=='https' ){
            curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, true );
            curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
            curl_setopt( $curl, CURLOPT_CAINFO, $cacert );
        }
        curl_setopt( $curl, CURLOPT_URL, trim( $url ) );
        curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
        curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
        curl_setopt( $curl, CURLOPT_FAILONERROR, true );
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 20 );
        curl_setopt( $curl, CURLOPT_TIMEOUT, 60 );
        curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' );
        curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 );
        curl_setopt( $curl, CURLOPT_ENCODING, '' );
        
        # add runtime options
        if( isset( $options ) && is_array( $options ) ){
            foreach( $options as $param => $value ) {
                curl_setopt( $curl, $param, $value );
            }
        }
        $res=(object)array(
            'response'  =>  curl_exec( $curl ),
            'status'    =>  curl_getinfo( $curl, CURLINFO_RESPONSE_CODE )
        );
        curl_close( $curl );
        
        return $res;
    }
    
    
    
    # create a temporary file to hold cookie data used by subsequent curl requests.
    $cookiejar=tempnam( sys_get_temp_dir(), '_cookiejar_' );
    
    # Target endpoint - initially loaded using GET to find cookies and parse the HTML to find the logintoken
    $url='https://grprek.jeddahknowledgeschool.com/login/index.php';
    
    # options used to make GET request. 
    # Cookie data will be saved to $cookiejar when curl_close() is called.
    $options=array(
        CURLOPT_COOKIESESSION   =>  true,
        CURLOPT_COOKIEJAR       =>  $cookiejar
    );
    
    # make the request and proceed if it succeeds
    $res=curl( $url, $options );
    if( $res->status==200 ){
        
        # The POST parameters to send. 
        # "logintoken" will be added below!
        $args=array(
            'username'      =>  'xxx',
            'password'      =>  'xxx'
        );
        
        
        # Load the HTML to find logintoken
        libxml_use_internal_errors( true );
        $dom = new DOMDocument;
        $dom->loadHTML( $res->response );
        libxml_clear_errors();
        
        
        #create an XPath to query the DOM and find INPUT elements within the form
        $xp=new DOMXPath( $dom );
        $expr='//form[ @class="login-form" ]//input';
        $col=$xp->query( $expr );
        
        # If the XPath succeeded, grab the name/value and assign as login arguments
        if( $col && $col->length > 0 ){
            # iterate through discovered inputs, add name/value to args array.
            # do not overwrite known values of username/password ( if known of course )
            # This is where the "logintoken" is added!
            foreach( $col as $node ){
                if( !array_key_exists( $node->getAttribute('name'), $args ) ){
                    $args[ $node->getAttribute('name') ]=$node->getAttribute('value');
                }
            }
            
            # create the curl options for the POST request.
            # use the cookie but do not start new cookie session.
            $options=array(
                CURLOPT_COOKIESESSION   =>  false,
                CURLOPT_COOKIEFILE      =>  $cookiejar,
                CURLOPT_POST            =>  true,
                CURLOPT_POSTFIELDS      =>  http_build_query( $args )
            );
            
            # make the curl request...
            $res=curl( $url, $options );
            if( $res->status==200 ){
                # Can progress no further or identify any errors beyond this point due to no valid credentials.
                # so simply print out HTML response that shows "Invalid login, please try again"
                # If the login succeeds then there will be different displayed HTML presumably.
                printf(
                    '<pre>%s</pre>',
                    print_r( $res->response, true )
                );
                
                
                #interested in seeing cookie?
                printf('<pre>%s</pre>',file_get_contents($cookiejar));
                
                # after all processing... erase cookie?
                unlink( $cookiejar );
            }else{
                printf( 'POST request failed with code: %s', $res->status );
            }
        }
    }else{
        printf( 'GET request failed with code: %s', $res->status );
    }
    
    Login or Signup to reply.
  2. but the login token I’m receiving is different from the actual one.

    what does that even mean? what is the actual one ?

    Anyhow, what you’re missing is the cookie session. the loginToken is tied directly to the cookie session, and without the cookie session, the loginToken is useless. You need to capture both the cookie session id and login token:

    <?php
    
    declare(strict_types=1);
    
    $ch = curl_init();
    curl_setopt_array($ch, array(
        CURLOPT_URL => 'https://grprek.jeddahknowledgeschool.com/login/index.php',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEFILE => '', // enables the curl cookie engine
    ));
    $html = curl_exec($ch);
    if(curl_errno($ch) !== CURLE_OK){
        throw new Exception(curl_error($ch));
    }
    $domd = new DOMDocument();
    @$domd->loadHTML($html);
    $xp = new DOMXPath($domd);
    $data = array();
    $data['loginToken'] = $xp->query('//input[@name="logintoken"]')->item(0)->getAttribute('value');
    $data['cookie_session'] = implode(" ", array_slice(explode("t", curl_getinfo($ch, CURLINFO_COOKIELIST)[0]), -2));
    print_r($data);
    

    prints:

    Array
    (
        [loginToken] => qs7hNrrJGGg1ok3p3Jllhi7yZS9hfuG6
        [cookie_session] => MoodleSession 1543c2992d6b6063f1b6da9ac77ed6cb
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search