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 );
}