-2

I have 2 forms : one for Registration and one for Login ([not on the same page, one is a modal][1])

(That's why I did 2 issets at the beginning)

The Registration one is working.

However the Login doesn't work because a User can log in with any password.

I want to verify username/email and of course password. How can I do it ?

Thank you!

Here is my code :

    // REGISTRATION
    if (isset($_POST['reg_user']) || isset($_POST['login_user'])) {
        $username = mysqli_real_escape_string($db, $_POST['name']);
        $email = mysqli_real_escape_string($db, $_POST['email']);
        $password = mysqli_real_escape_string($db, $_POST['password']);
        
        $hashed_password = password_hash($password, PASSWORD_DEFAULT);

        $query = "SELECT * FROM utilisateur WHERE pseudoUtil='$username' OR mailUtil='$email'";
        $results = mysqli_query($db, $query);
        if(mysqli_num_rows($results) == 1){
            $_SESSION['message'] = "User already exists !"; 
        }
        else{
            mysqli_query($db, "INSERT INTO utilisateur (pseudoUtil, mailUtil, pwdUtil) VALUES ('$username', '$email', '$hashed_password')");
            $_SESSION['message'] = "Registration complete :)"; 
        }

        // LOGIN
        if (isset($_POST['login_user'])) {
                        
                
            $query2 = "SELECT $hashed_password FROM utilisateur WHERE pseudoUtil='$username' OR mailUtil='$email'";
            $results2 = mysqli_query($db, $query2);

            if(mysqli_num_rows($results2) == 1){
                $_SESSION['username'] = $username;
                header('location: index.php'); 
            }
            else{
            }
        }
    }
    else{
    }

  [1]: https://i.stack.imgur.com/fCdAV.png
YapYap31
  • 1
  • 2
  • registration needs to create the password hash and save it to the database, log in needs to pull the hash from the database and compare to the password – MikeT Aug 12 '22 at 09:28
  • 2
    Why is your `// LOGIN` code _inside_ the if condition you have wrapped around the whole `// REGISTRATION` process, to begin with? – CBroe Aug 12 '22 at 09:30
  • 2
    You should stop using `mysqli_real_escape_string()` as it's [not as secure as you might think](https://stackoverflow.com/questions/32391315/is-mysqli-real-escape-string-enough-to-avoid-sql-injection-or-other-sql-attack). Use prepared statements using placeholders instead. You can read [how to prevent SQL injection in PHP](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) to get a quick example of how to use them. Also, _never_ escape or change the users password. Just create a hash from the password "as-is" and store that hash. – M. Eriksson Aug 12 '22 at 09:41
  • 1
    `password_verify($password, $hashed_password)` will _always_ be true. `$password` contains the value sent in `$_POST['password']` and `$hashed_password` is the hash of `$password` (created on the 7th line in the posted code). So you're just comparing the posted password against itself (which obviously will always be a match) – M. Eriksson Aug 12 '22 at 09:46
  • @CBroe because i had to use the $hashed_password variable created in the Registration – YapYap31 Aug 12 '22 at 10:31
  • 1
    That is one of the worst justifications I have ever heard. Plus, what you are doing, does not even make sense. You create `$hashed_password` based on `$password`, and then later on you do `password_verify($password, $hashed_password)` - you did not even read the actual hashed password of the user from the database here, you are comparing two hashes calculated on the _same_ input variable. – CBroe Aug 12 '22 at 10:37
  • I updated the code. However i am still having trouble with `mysqli_num_rows($results2) == 1`. I have this error message : **Fatal error: Uncaught TypeError: mysqli_num_rows(): Argument #1 ($result) must be of type mysqli_result, bool given** – YapYap31 Aug 12 '22 at 11:31
  • Google that error message and you'll soon find existing explanations for it – ADyson Aug 12 '22 at 11:36
  • Does this answer your question? [How to use PHP's password\_hash to hash and verify passwords](https://stackoverflow.com/questions/30279321/how-to-use-phps-password-hash-to-hash-and-verify-passwords) – ADyson Aug 12 '22 at 11:37

1 Answers1

0

registration needs to create the password hash and save it to the database, log in needs to pull the hash from the database and compare to the password

both of these tasks should be complete isolated from each other

this means your code should look more like this note this is an example only not tested as working

POST /register body: username=someone@some.where&password=123456789

function Register(){
    $stmt = $mysqli->prepare("SELECT count * as count FROM users WHERE email=?");
    $stmt->bind_param("s", $_POST["username"]);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if($result->fetch_array(MYSQLI_ASSOC)["count"]>0)
    {
        return "User already exists"
    }
    else
    {
        $hash = password_hash($_POST["password"],PASSWORD_DEFAULT);
        $stmt = $mysqli->prepare("INSERT INTO users (username, hash) values (?,?)");
        $stmt->bind_param("ss", $_POST["username"], $hash);
        $stmt->execute();
        $result = $stmt->get_result();
        //either return success or set up as a successful login and perform login action
    }
 }

POST /login body: username=someone@some.where&password=123456789

 function Login(){
    $stmt = $mysqli->prepare("SELECT hash FROM users WHERE email=?");
    $stmt->bind_param("s", $_POST["username"]);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if(password_verify($_POST["password"], $result->fetch_array(MYSQLI_ASSOC)["hash"]))
    {
        //do successful login 
    }
    else
    {
        //log in failed
    }
 }
MikeT
  • 5,398
  • 3
  • 27
  • 43