Chonchol Mahmud Chonchol Mahmud - 3 months ago 15
PHP Question

Password is not matching for my PHP login form

I have tried many times but every time its says

Email & Password Not Matched!
.I can not find any solution of it.I have used PDO for database connection.I think i have problem with session value.But i can not find the error.I have tried so far:

<?php
/* For Login */

include 'db.php';
if (isset($_POST['login'])) {
$email = $_POST['email'];
$hash = $_POST['password'];
$password = password_hash($hash, PASSWORD_DEFAULT);
$records = $db->prepare("SELECT id FROM users WHERE email=? AND password=?");
$records->execute(array($email,$password));
$userdata = $records->fetch(PDO::FETCH_ASSOC);
if (!empty($email) && !empty($hash)) {
if (count($userdata)>0 ) {
//session_start();
$_SESSION['email'] = $userdata['email'];
$_SESSION['password'] = $userdata['password'];
if ($_POST['password'] == $userdata['password']) {
echo "<div class='alert alert-success text-center'>
<strong>Successfully</strong> Login</div>";
exit;
}else{
echo "<div class='alert alert-danger text-center'>
<strong>Email & Password</strong> Not Matched!
</div>";
}
}else{
echo "Email and Password Not Matched!";
echo $_SESSION['email'];
}
}else{
echo "<div class='alert alert-danger text-center'>
<strong>Email & Password</strong> must not be empty!</div>";
}
}
?>


Thanks in advance.

Answer

You are re hashing the incoming password, that is not how its done with password_hash() you need to use password_verify() to test that the hashed password on the database in the same as the plain text password passed in by the user.

If you run password_hash() using the same password twice in a row you will get a different hash each time, therefore you must use password_verify() to verify the entered password against the hashed one on the database.

Try this from the CLI and it will demonstrate:

$password = 'WoopsADaisy';
echo password_hash($password, PASSWORD_DEFAULT).PHP_EOL;
echo password_hash($password, PASSWORD_DEFAULT).PHP_EOL;

The output, only when I ran it as a test returns

$2y$10$t52UeqDlP897iD/n6uo71OErIFP5c4wsli6gLRNdfyQLkv8m6Wxs2
$2y$10$FczpgQIsmpzr6.vhYA6d3.QmEe3i3HR4WkapLrtO/BLK4Uul0WjUa

You wont get the same hashes, but you will get 2 different hashes!

This also means you need to mod your process a little

<?php
/* For Login */

// always start the session at the top of a script
session_start();

include 'db.php';

// isset can test many variables at the same time
if (isset($_POST['login'], $_POST['email'], $_POST['password'])) {
    $email      = $_POST['email'];
    $plain_pwd  = $_POST['password'];

    // get hashed password to test
    // also you were never actually retrieving the email
    $records = $db->prepare("SELECT id,password,email 
                             FROM users WHERE email=?");
    $staus = $records->execute(array($email));

    // test the query actually worked
    if ( $staus === false ) {
        print_r($db->errorInfo());
        exit;
    }

    $userdata = $records->fetch(PDO::FETCH_ASSOC);



    if ( password_verify($plain_pwd, $userdata['password']) ) {
        // the entered password is GOOD

        $_SESSION['email'] = $userdata['email'];

        // never need to store in session
        //$_SESSION['password'] = $userdata['password'];

        echo "<div class='alert alert-success text-center'>
              <strong>Successfully</strong> Login</div>";
    } else {
        echo "Email and Password do not Match!";
    }

}else{
    echo "<div class='alert alert-danger text-center'>
          <strong>Email & Password</strong> must not be empty!</div>";
}
?>

Something else that can trip you up when hashing passswords. Make sure that the column password on your table is long enough to hold the hashed password. 60 chars in what password_hash() created using PASSWORD_DEFAULT but as the default hash algorithm may change over time should it need strengthening, it is recommended to make this column a varchar(255) to keep your database future proof.

References :

password_hash()

password_verify()

Comments