I have a processing file for a login to an app. I either do not understand the purpose of password_needs_rehash()
or it is not working. The login is authenticating and passing me through to the correct page. But I can't get the code to even echo the new hash.
Am I doing this correctly?
Does the if
not throw a new hash because it does not need rehashed? If so when would a password need rehashed if it was properly hashed and stored in the DB?
My processing file is below:
$email = $_POST["li_email"];
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$stmt = $conn->query("SELECT * FROM users WHERE email='$email'");
$stmt->execute();
while($row=$stmt->fetch()){ //for each result, do the following
$hash = $row['hash'];
$userPassword = $_POST["li_password"];
if (password_verify($userPassword, $hash)) {
if ( password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12]) ) {
$newhash = password_hash($userPassword, PASSWORD_DEFAULT, ['cost' => 12]);
echo $newhash;
}
} else {
header('Location: http://' . $_SERVER['HTTP_HOST'] . '?error=loginfailed');
exit();
}
}
} catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
Thank you for the help!
The function password_needs_rehash()
only needs to be used if you change the $options
which usually refers to the cost
.
The more the cost, the more CPU time it takes to hash the password but the more difficult it becomes to crack it. If you change hosting or move over to a cloud based system where multiple computers can calculate the hash for you, you are able to increment it at your own discretion.
You only need to check if the password needs a rehash at user login, since password_verify()
can still verify the password if you changed the $options
. If password_needs_rehash()
returns true at that point, use password_hash()
with the new options and replace the old hash.
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$stmt = $conn->prepare($sql = "SELECT * FROM users WHERE email=?"); // otherwise $sql is not defined in catch()
if($stmt->execute([$_POST["li_email"]])){
// preventing sql injection
if(($data = $stmt->fetch()) != false){
// only expecting 1 row from db since an email should be unique.
if(password_verify($_POST["li_email"], $data['hash'])){
// valid login
if(password_needs_rehash($data['hash'], PASSWORD_DEFAULT, $options = ['cost' => 12])){
$newhash = password_hash($_POST["li_email"], PASSWORD_DEFAULT, options);
// store new hash in db.
}
} else {
header('Location: http://' . $_SERVER['HTTP_HOST'] . '?error=loginfailed');
exit();
}
} else {
// no results
}
} else {
// query failed
}
} catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With