简体   繁体   中英

password_verify returning false with correct password

So I am trying to verify the hashed password of the user from MySQL DB but password_verify doesn't seem to be working. I feel like maybe it is something I am doing wrong.

Hashing and Storing the Password:

// Set POST variables
$firstname = mysqli_real_escape_string($conn, $_POST['firstname']);
$lastname = mysqli_real_escape_string($conn, $_POST['lastname']);
$email = mysqli_real_escape_string($conn, $_POST['email']);
$password = mysqli_real_escape_string($conn, $_POST['password']);
$hashedpwd = password_hash($password, PASSWORD_DEFAULT);

// SQL query & Error Handlers
$sql = "INSERT INTO `users_admin` (Firstname, Lastname, Email, Password) VALUES ('$firstname', '$lastname', '$email', '$hashedpwd')";

Retrieving the Hashed Password:

 if ($row = mysqli_fetch_assoc($result)) {
        $user_pass = $row['Password'];
        $passwordCheck = password_verify($password, $user_pass);
        if (!$passwordCheck) {
            header("Location: ../login.php?wrong-password");
            exit();
        } elseif ($passwordCheck) {
            // log in the user
            $_SESSION['logged_in'] = true;
            $_SESSION['id'] = $row['ID'];
            $_SESSION['firstname'] = $row['Firstname'];
            $_SESSION['lastname'] = $row['Lastname'];
            $_SESSION['email'] = $row['Email'];
            header("Location: ../dashboard");
            exit();

        }
    }

password_verify = bool(true)

EDIT:

if (isset($_POST['submit'])) {

include('DB_Connect.php');

$email = mysqli_real_escape_string($conn, $_POST['email']);
$password = mysqli_real_escape_string($conn, $_POST['password']);

// error handlers
$sql = "SELECT * FROM users_admin WHERE Email = '$email'";
$result = mysqli_query($conn, $sql);
$resultCheck = mysqli_num_rows($result);
if ($resultCheck < 1) {
    header("Location: ../login.php?input:invalid");
    exit();
} else {
    if ($row = mysqli_fetch_assoc($result)) {
        $user_pass = $row['Password'];
        $passwordCheck = password_verify($password, $user_pass);
        if (!$passwordCheck) {
            header("Location: ../login.php?wrong-password");
            exit();
        } elseif ($passwordCheck) {
            // log in the user
            $_SESSION['logged_in'] = true;
            $_SESSION['id'] = $row['ID'];
            $_SESSION['firstname'] = $row['Firstname'];
            $_SESSION['lastname'] = $row['Lastname'];
            $_SESSION['email'] = $row['Email'];
            header("Location: ../dashboard");
            exit();

         }
     }
  }
}else{
    header("Location: ../login.php?login=error");
    exit();
}

There is nothing on the code you posted that leads to the problem described.

Here are some hints and improvements:

1.

You are escaping/sanityzing the password before hashing it.

This way you're altering the stored password

Let

$password = $_POST['password'];

both when you create the account and when you check if the password match at login.

2.

Ensure the Password field in the database (that stores the hashed password) is able to store up to 255 characters.

From the documentation

it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).

If the field is narrower the hash will be truncated and you'll never have a match.

3.

As you get the user by email at login ensure that Email is unique (as long as your primary key ID ) at database level (in the table definition).

Good idea to check this also upon user registration and login (at php level).

4.

Keys in the Key-Value pairs returned by mysqli_fetch_assoc are case sensitive . Ensure you access the values using keys written exactly as the field are named in the database.

Ex. in your code I read $row['Email'] . In the table is the field name actually Email or maybe it's email (lowercase) ?

5.

Debug your code!

Use a debugger or simply place a breakpoint like

var_export( $the_variable );
exit();

in "key" points of your code.

6.

Use prepared statements instead of escaping input and injecting it directly into the SQL strings.


Hashing and Storing the Password:

// Set POST variables
$firstname = mysqli_real_escape_string($conn, $_POST['firstname']);
$lastname = mysqli_real_escape_string($conn, $_POST['lastname']);
$email = mysqli_real_escape_string($conn, $_POST['email']);
$password = $_POST['password'];
$hashedpwd = password_hash($password, PASSWORD_DEFAULT);

// SQL query & Error Handlers
$sql = "INSERT INTO `users_admin` (Firstname, Lastname, Email, Password) VALUES ('$firstname', '$lastname', '$email', '$hashedpwd')";

Retrieving the Hashed Password:

include('DB_Connect.php');

$email = mysqli_real_escape_string($conn, $_POST['email']);
$password = $_POST['password'];

$sql = "SELECT * FROM users_admin WHERE Email = '$email'";
$result = mysqli_query($conn, $sql);

if( $result === false )
{
    header("Location: ../login.php?login=error");
    exit();
}

$count = mysqli_num_rows($result);
if( $count === 0 )
{
    header("Location: ../login.php?input:invalid");
    exit();
}

$row = mysqli_fetch_assoc( $result );

$passwordHash = $row['Password'];
$passwordCheck = password_verify( $password, $passwordHash );
if( ! $passwordCheck )
{
    header("Location: ../login.php?wrong-password");
    exit();
}

// log in the user
$_SESSION['logged_in'] = true;
$_SESSION['id'] = $row['ID'];
$_SESSION['firstname'] = $row['Firstname'];
$_SESSION['lastname'] = $row['Lastname'];
$_SESSION['email'] = $row['Email'];
header("Location: ../dashboard");
exit();

Paolo's answer is good and answers your question, I just wanted to explain to you why your passwords are not the same .

First, you take the POSTed password and escape it:

$password = mysqli_real_escape_string($conn, $_POST['password']);

And then you hash the escaped password :

$hashedpwd = password_hash($password, PASSWORD_DEFAULT);

But here:

$passwordCheck = password_verify($password, $user_pass);

You password_verify the unescaped password (I assume as you didn't publish the full code)

To solve this issue, do not escape the password, a better solution as Paolo suggested in his answer is to use Prepared Statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM