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:

  1. If 2fac is not enabled then check credentials/ password hash then login.
  2. If 2fac is enabled then check if password is still correct then redirect to 2factcode.php for code verification.
  3. 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.

Source