Search code examples
phppasswordsverify

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

Solution

  • 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();