Search code examples
phpcurlcookiesauthenticationcsrf

How to login on website with PHP Curl library?


I want to login to a page on https using the PHP CURL library. Reload this Page. But I couldn't. I could not make the connection from the server or localhost.

 $username = "[email protected]";
$password = "Bf*****";
$url = "https://eksisozluk.com/giris";
$cookie= "cookies.txt";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) die(curl_error($ch));
$dom = new DomDocument();
$dom->loadHTML($response);
$tokens = $dom->getElementsByTagName("meta");
for ($i = 0; $i < $tokens->length; $i++)
{
    $meta = $tokens->item($i);
    if($meta->getAttribute('name') == 'csrf-token')
    $token = $meta->getAttribute('content');
}
$postinfo = "UserName=".$username."&Password=".$password."&_csrf=".$token;
echo $token; //debug info
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postinfo);
$html = curl_exec($ch);
    print($html);
if (curl_errno($ch)) print curl_error($ch);
    curl_close($ch);

I'm printing a cookie. Just giving you a blank sheet. I'm getting the error message.


Solution

  • you try to send the login credentials before getting a cookie, but the website requires you to already have a cookie PRIOR to logging in. also, the website use a CSRF token which you need to fetch prior to logging in, but you don't. also, your username and password needs to be urlencoded, but you don't urlencode it, for example the @ is wrong, it should have been Username=pik123%40gmail.com (@ urlencoded is %40 ), also the username variable is called UserName, not Username,

    first fetch the login page with a normal GET request, this will get you both the cookie you need, and the CSRF token,

    then parse out the CSRF token, and send a POST request to the login page with the cookie and the CSRF token in the application/x-www-form-urlencoded format, with __RequestVerificationToken as the CSRF token and UserName as the username (and be more careful with the CaPiTaLiZaTiOn here, it's UserName, not Username), and Password as the password, and a seemingly hardcoded parameter called ReturnUrl which just contains / (urlencoded ofc, which is %2F, eg ReturnUrl=%2F), and you should get logged in (your cookie session will now be logged in), provided you have valid credentials.

    example with the hhb_curl library (which takes care of cookie handling and curl error checking, converting curl errors to RuntimeExceptions):

    <?php
    declare (strict_types = 1);
    require_once('hhb_.inc.php');
    $username = "[email protected]";
    $password = "Bf*****";
    $hc = new hhb_curl('', true);
    // get cookie and csrc token:
    $html = $hc->exec('https://eksisozluk.com/giris')->getStdOut();
    $domd = @DOMDocument::loadHTML($html);
    $xp = new DOMXPath($domd);
    // grab the login form (it contains the csrf token, among other things)
    $login_form = $xp->query("//form[contains(@action,'/giris')]")->item(0);
    $login_parameters = array();
    foreach ($login_form->getElementsByTagName("input") as $input) {
        $login_parameters[$input->getAttribute("name")] = $input->getAttribute("value");
    }
    // the CSRF token is called `__RequestVerificationToken`, and $login_parameters now contains roughly:
    // array(
    //  '__RequestVerificationToken' => 'qTk2Ik0glfV8W1WckmrVkVXujQE8C1eTqMEe36SP-PPUXDn88GG0XYxif3ZMIVGZH08-MEbbtD7i7Q4ymxuasveDZL-WaHQH22r33fOdsqQ1',
    //  'ReturnUrl' => '/',
    //  'UserName' => '',
    //  'Password' => '',
    //  'RememberMe' => 'false',
    // );
    assert(isset($login_parameters['UserName']));
    assert(isset($login_parameters['Password']));
    $login_parameters['UserName'] = $username;
    $login_parameters['Password'] = $password;
    // log in
    $html = $hc->setopt_array(array(
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => http_build_query($login_parameters)
    ))->exec()->getStdOut();
    // check for login errors:
    $domd = @DOMDocument::loadHTML($html);
    $xp = new DOMXPath($domd);
    $login_errors = array();
    foreach ($xp->query("//*[contains(@class,'validation-error')]") as $login_error) {
        $login_error = trim($login_error->textContent);
        if (!empty($login_error)) {
            $login_errors[] = $login_error;
        }
    }
    unset($login_error);
    if (!empty($login_errors)) {
        throw new \RuntimeException("eksisozluk login errors: " . print_r($login_errors, true));
    }
    

    output:

    $ php wtf4.php
    PHP Fatal error:  Uncaught RuntimeException: eksisozluk login errors: Array
    (
        [0] => captcha'yı yanlış girdiniz.
    )
     in /cygdrive/c/projects/misc/wtf4.php:46
    Stack trace:
    #0 {main}
      thrown in /cygdrive/c/projects/misc/wtf4.php on line 46