php - unable to apply two different conditions and also check password hash
Quick check on this one that I am trying to figure out. First of all I want to apologize if I hurt your eyes with my code, I just started two weeks ago with php and I am trying my best applying the logic :-D
So 2 factor was just implemented via user profile, meaning that if the feature is still not enable the user can still login successfully, after the 2 fact is enabled then he will be redirected to verify the code. with that said the login.php post will need to check the following:
- If 2fac is not enabled then check credentials/ password hash then login.
- If 2fac is enabled then check if password is still correct then redirect to 2factcode.php for code verification.
- error if the password is incorrect in either 1 or 2.
'''
$email=mysqli_real_escape_string($db,$_POST['email']);{
$password=mysqli_real_escape_string($db,$_POST['password']);
$stmt = $db->prepare("SELECT password FROM users WHERE email = ? AND isEmailConfirmed='1' AND is2facEnabled='0'");
$stmt->bind_param("s", $_POST['email']);
$stmt->execute();
$stmt->bind_result($hash);
//checking hash
if ($stmt->fetch() && password_verify($_POST['password'], $hash)) {
$_SESSION['email'] = $email;
header('location: prod.php');
'''
- So here is what I've been trying to tweak (not sure if makes sense), if the statement is not valid meaning no rows were found because is2facenabled value is '1', then I still check if password hash is correct then go to verify 2fac code.*
If I remove the password check below then it works but it never checks if the password is correct, if I leave it how it is then if I put a wrong password the page refresh with no errors and goes back to enter credentials. I think it has an issue with the $_POST but not sure.
elseif (!$stmt->fetch() && password_verify($_POST['password'], $hash)) {
header('location: login2factorverification.php');
}else {
array_push($errors, "Incorrect credentials or email needs verification");
enter code here
my question is, how do I accomplish these checks and login properly, thank you in advance.
Regards, MF
Answer
Solution:
This basically amounts to what I consider the first rule of programming: Break The Problem Down.
Rather than trying to write one piece of code that checks user existence, password, and 2fac status, do one at a time:
- Select details from the database based on the provided email address. If no row is found, they're not registered, so you don't need to do anything else.
- You could include the "is address confirmed" check in the SQL, or you could write it as a separate if statement before checking anything else.
- Next, check the password provided is correct. If it's not, it doesn't matter if the user has 2fac enabled or not, because you're not going to let them log in.
- Finally, check if the user has 2fac enabled. If they do, redirect to the 2fac step; if they don't, mark them as successfully logged in.