7

I worked with HttpFox and have compared the values (url and post data) with the ones my code has generated. They are completely the same, but I always see the message 'Login failed' on the webpage. I have no idea what could be the problem.

Code:

require 'domparser_1_5/simple_html_dom.php';

$username = "username";
$password = "password";

function login($url,$data){
    $fp = fopen("cookie.txt", "w");
    fclose($fp);
    $login = curl_init();
    curl_setopt($login, CURLOPT_URL, $url);
    curl_setopt($login, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($login, CURLOPT_COOKIEJAR, "cookie.txt");
    curl_setopt($login, CURLOPT_COOKIEFILE, "cookie.txt");
    curl_setopt($login, CURLOPT_TIMEOUT, 40000);
    curl_setopt($login, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($login, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($login, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($login, CURLOPT_POST, true);
    curl_setopt($login, CURLOPT_POSTFIELDS, $data);
    ob_start();
    $result = curl_exec($login);
    ob_end_clean();
    curl_close($login);
    unset($login);
    return $result;
}

function generate_pass($user, $password, $token) {
    if ($password) {
        $enc_pass = md5($password);
        $pass = $user.':'.$enc_pass.':'.$token;
        return md5($pass);
    }
}

function get_token() {
    $html = file_get_html('https://www.foo.com/');
    $token = "";
    foreach($html->find('input') as $element) {
        if($element->name == "token") {
            $token = $element->value;
        }
    }
    if (!$token) {
        die('No token found');
    }
    return $token;
}

$token = get_token();

echo login("https://www.foo.com/login/start.html", "user=".$username."&password=".$password."&submit=Anmelden&logintype=login&pid=4%2C93%2C1828&pass=".generate_pass($username, $password, $token)."&redirect_url=login%2Fstart.html&tx_felogin_pi1%5Bnoredirect%5D=0&token=".$token."");
11
  • Try to use Guzzle lib, it's more user-friendly. github.com/guzzle/guzzle Commented Apr 24, 2015 at 8:46
  • Or you can add Postman Plugin (chrome.google.com/webstore/detail/postman-rest-client/…), send your request and see if it really works... Commented Apr 24, 2015 at 8:48
  • Why do you have code after return curl_exec($login);? The function ends when you use return. Commented Apr 24, 2015 at 8:49
  • @vanadium23 thanks, I will try this. But it's still interesting for me why the code isn't working. Commented Apr 24, 2015 at 9:23
  • @GuilhermeFerreira this isn't that easy, because the form of the external webpage generates an individuell token each time you are try to log in. Commented Apr 24, 2015 at 9:23

1 Answer 1

1

Authentication fails due to the mismatch between token and cookie(s) passed.

When you load the page to retrieve the token with get_token() the server is sending you a cookie that you are not saving.

Later when you try to login the server expects to receive same cookie it sent you when you got the token. But you're not sending it.

I suggest you to the rewrite get_token() using curl and storing cookies in cookie.txt. This will let you pass them later when you'll call login()

Like this:

function get_token() {
    $url = 'https://www.foo.com/';
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_COOKIEJAR, "cookie.txt");
    curl_setopt($curl, CURLOPT_COOKIEFILE, "cookie.txt");
    curl_setopt($curl, CURLOPT_TIMEOUT, 40000);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    $result = curl_exec($curl);
    curl_close($curl);
    unset($curl);

    $html = str_get_html( $result );
    $token = "";
    foreach($html->find('input') as $element) {
        if($element->name == "token") {
            $token = $element->value;
        }
    }
    if (!$token) {
        die('No token found');
    }
    return $token;
}

Important:

Remove

$fp = fopen("cookie.txt", "w");
fclose($fp);

From login() as that truncates to zero bytes the cookie.txt file, and you don't want to delete the cookie just retrieved.

Note that curl_exec() creates the speciefied cookie file if it doesn't exist.

Sign up to request clarification or add additional context in comments.

3 Comments

Okay, that sounds logical. Can you give me a code snippet how you would do this?
Basically you merge the login function without passing post data and the original get_token using str_get_html to initialte html parsing. I posted a snippet. Of course I assume the rest of your code (as you get the token from the htm, how you pass login and pass to the website) is correct. Imprortant doon't truncate cookie.txt into login() see answer
Also... get the token. Store into variable. Then generate the password. Then do the login. This avoids loading the home page twice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.