-1

I am making a login and registration form and I use password_hash for password encryption, the problem is that when I log in it does not recognize my password and I get the error "the password is incorrect" (a message that I set). In the registration form there are no problems, but maybe it has to do with the error that I have.

Login.php

<?php
include 'connect/config.php';
session_start();
error_reporting(0);

if (isset($_SESSION["user_id"])) {
  header('Location: home');
}

if (isset($_POST["signin"])) {
  $email = mysqli_real_escape_string($conn, $_POST["email"]);
  $password = mysqli_real_escape_string($conn, $_POST["password"]);

  $check_email = mysqli_query($conn, "SELECT id FROM users WHERE email='$email' AND password='$password'");

  if (mysqli_num_rows($check_email) > 0) {
    $row = mysqli_fetch_array($check_email);
    $_SESSION["user_id"] = $row['id'];
    if (password_verify($password, $row['password'])){
        $msg[] = "You have successfully logged in.";
    }
    header('Location: home');
    
  } else {
    $msg[] = "The password or email is incorrect.";
  }
}
?>

Now, if I change the $check_email = mysqli_query($conn, "SELECT id FROM users WHERE email='$email' AND password='$password'"); to $check_email = mysqli_query($conn, "SELECT id, password FROM users WHERE email='$email'"); I can enter the home, but with any password and not the one I registered with.

Registration.php

<?php

include 'connect/config.php';
session_start();
error_reporting(0);

if (isset($_SESSION["user_id"])) {
    header("Location: home");
  }
if (isset($_POST["signup"])) {
    $full_name = mysqli_real_escape_string($conn, $_POST["signup_full_name"]);
    $email = mysqli_real_escape_string($conn, $_POST["signup_email"]);
    $password = mysqli_real_escape_string($conn, $_POST["signup_password"]);
    $cpassword = mysqli_real_escape_string($conn, $_POST["signup_cpassword"]);
    $token = md5(rand());
  
    $check_email = mysqli_num_rows(mysqli_query($conn, "SELECT email FROM users WHERE email='$email'"));
  
    if ($password !== $cpassword) {
      $msg[] = "Passwords do not match";
    } elseif ($check_email > 0) {
      $msg[] = "The email already exists, try another.";
    } else {
      $passHash = password_hash($password, PASSWORD_BCRYPT);
      $sql = "INSERT INTO users (full_name, email, password, token, status) VALUES ('$full_name', '$email', '$passHash', '$token', '0')";
      $result = mysqli_query($conn, $sql);
      if ($result) {

        header('Location: login');

        $_POST["signup_full_name"] = "";
        $_POST["signup_email"] = "";
        $_POST["signup_password"] = "";
        $_POST["signup_cpassword"] = "";
        $msg[] = "Registered user successfully.";
      } else {
        $msg[] = "User registration failed, please try again later.";
      }
    }
}
?>

I hope you can help me.

Review my code but my low level of knowledge in php prevents me from finding the error, I hope you can do it for me, I will thank you

Dev.Fra
  • 11
  • 2
  • 2
    Your script is vulnerable to [SQL Injection Attack](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php). Even if [you are escaping variables, its not safe](https://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string%5D)! You should always use [prepared statements and parameterized queries](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php) in either MYSQLI or PDO instead of concatenating user provided values into the query. – Barmar Nov 09 '22 at 20:41
  • **WARNING**: Writing an access control layer is not easy and there are many opportunities to get it severely wrong. Any modern [development framework](https://www.cloudways.com/blog/best-php-frameworks/) like [Laravel](http://laravel.com/) comes with an [authentication system](https://laravel.com/docs/master/authentication) built-in. – tadman Nov 09 '22 at 20:45
  • Only inside the `if (password_verify())` you should allow a login, you do it whenever a row was found. – martinstoeckli Nov 09 '22 at 20:45
  • [Login system cant log in](https://stackoverflow.com/q/6862851/2943403) – mickmackusa Nov 09 '22 at 21:20

1 Answers1

1

You should not have and password = '$password' in the query. The password in the database is the hashed password, not the same as $password. You should just fetch the row using the email, then use password_verify() to check the password.

You also need to select the password column so you can verify it.

$check_email = mysqli_query($conn, "SELECT id, password FROM users WHERE email='$email'");

You also have problems with your logic. You set the session variable and redirect to home regardless of the password verification. It should be:

$row = mysqli_fetch_array($check_email);
    
if ($row && password_verify($password, $row['password'])){
    $msg[] = "You have successfully logged in.";
    $_SESSION["user_id"] = $row['id'];
    header('Location: home');
} else {
    $msg[] = "The password or email is incorrect.";
}

You also shouldn't escape the password before hashing or verifying it. And of course, if you correctly use prepared statements with parameters, you shouldn't escape anything first.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • now i changed `SELECT id FROM users WHERE email='$email' AND password='$password'` to `SELECT id FROM users WHERE email='$email'` but it keeps redirecting to home if i type wrong password. – Dev.Fra Nov 09 '22 at 20:51
  • It should be `SELECT id, password ...`. Otherwise, how do you expect to get `$row['password']`? – Barmar Nov 09 '22 at 20:55
  • Now it's like this `SELECT id, password FROM users WHERE email='$email'` but it still redirects me to home with wrong password – Dev.Fra Nov 09 '22 at 20:58
  • Your redirect isn't inside the `if`, so it happens whether or not the password is correct. – Barmar Nov 09 '22 at 21:01
  • sorry, it was my mistake, i forgot to put "header location" inside the if verify, that's why i was logging in with any password. – Dev.Fra Nov 09 '22 at 21:03
  • Another question, how do I never log out after closing the browser or keep the session open even after being away for 1 week? similar to what facebook does, sessions are never closed, your account is still active even after not logging in for 1 week. – Dev.Fra Nov 09 '22 at 21:07
  • You need to configure session timeouts in your php.ini – Barmar Nov 09 '22 at 21:09