0

Hi I am tired of doing and debugging this task. I read several similar questions in the Stackoverflow.com, but unable to find a solution. The problem is that despite using same hashing method (suppose md5, hash) for both Registering and Login, every time I try to login it shows unmatched password.

I am using 'InsertUsers' class in which there is a method named 'userLogin' to which I send two arguments (userName and userPassword) from the 'login.php' file. Before sending as an argument I encrypted the password. But It says unmatched password.

When I checked the password sent by the login.php after hashing I found this string $2y$10$./syQEE.LiMBynyanGXmeei1lk/fgZrQ/K4V6PBpjsc3nlBMh6gd6 instead of the stored string (stored by registration page) $2y$10$1vrJ3Sq19uGjkIG9YG4NmOF.

Apart from unmatched issue, every time I enter the same password the login page hashed password is seen slight different. Below is the code I used. Please help me in finding out the problem. I went through several questions in Stackoverflow, but none of them matched for my problem.

In the registration.php I encrypted like this-

$user_pass = password_hash($_POST['password'], PASSWORD_DEFAULT);

And in the InsertUsers class in my userLogin method is

public function userLogin($userName, $userPassword){
    try{
        $sql = "SELECT id FROM users WHERE user_name = ? AND password = ?";
        $stmt = $this->connect()->prepare($sql);
        $stmt->bindParam(1, $userName,PDO::PARAM_STR);
        $stmt->bindParam(2, $userPassword,PDO::PARAM_STR);
        $stmt->execute();
        if($stmt->rowCount() > 0){
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result['id'];
        }
        else{
                return false;
        }
    }
    catch (PDOException $e) {
        echo 'Error, Please put correct data' .$e->getMessage();
    }
}

In login.php file I encrypted the password before sending it to the above method.

if((empty($_POST['username'])) || empty($_POST['password'])){
        array_push($error_message, "User Name & Password required");
}
    else{
        $userName = $_POST['username'];
        $userPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
    }   


if(empty($error_message)){
    $Login = new InsertUsers();
    $loginCheck = $Login->userLogin($userName, $userPassword);
    if($loginCheck > 0){
        $_SESSION['username'] = $_POST['username'];
        echo "Hello ". $_SESSION['username'];
    }
    else{
        echo "password not matched";
    }
}
Community
  • 1
  • 1
As Dictionary
  • 41
  • 1
  • 6
  • You cannot search for the hashed and salted password with Sql, the hash will look different for every calculation. Have a look at this [example code](https://stackoverflow.com/a/38422760/575765), it shows how you can verify a password. – martinstoeckli Dec 15 '18 at 14:48

1 Answers1

0

password_hash() doesn't return the same hash each time, so use password_verify().

public function userLogin($userName, $userPassword){
    try{
        $sql = "SELECT id FROM users WHERE user_name = ? AND password = ?";
        $stmt = $this->connect()->prepare($sql);
        $stmt->bindParam(1, $userName,PDO::PARAM_STR);
        $stmt->bindParam(2, $userPassword,PDO::PARAM_STR);
        $stmt->execute();

        $result = $stmt->get_result();

        while ($row = $result->fetch_assoc()) {
            $hashed_password = $row['password'];
        }

        if($stmt->rowCount() > 0){
            if (password_verify($userPassword, $hashed_password)) {
                return $result['id'];
            }
        }
        else{
                return false;
        }
    }
    catch (PDOException $e) {
        echo 'Error, Please put correct data' .$e->getMessage();
    }
}

Also, you should increase the length of your column to 255 characters.

Panda
  • 6,955
  • 6
  • 40
  • 55
  • Thanks for notifying me the length. But are you sure that the get_result() and fetch_assoc() work in this way in PDO. I am using PDO. Besides, should I send the password from the login.php in hashed form? Or should I send it in plain text? – As Dictionary Dec 14 '18 at 05:45
  • @AsDictionary No problem, it should work and it should be sent in plain text. – Panda Dec 14 '18 at 05:51
  • If I send the plain text password how does my sql statement will compare it with the hashed password stored in the database and fetch it to verify in later part of the code? – As Dictionary Dec 14 '18 at 06:08
  • @AsDictionary `password_verify()` will check the plain text password with the one hashed in the database. – Panda Dec 14 '18 at 06:22
  • That I understand. But how does my SQL statement will fetch data to check by the password_verify() function where password of the database (which is hashed) = $userPassword (which is plain text). Since both are not equal the sql statement will not fetch any row, Will it? – As Dictionary Dec 14 '18 at 07:09
  • @AsDictionary I think you can simply fetch the row with the correct username – Panda Dec 14 '18 at 08:13