0
<?php
session_start();
include 'dbh.inc.php'; //The connection ($conn) is working

$errors = array();  

    //Login
    if (isset($_POST['login'])) {
        $username = $_POST['username'];
        $password_1 = $_POST['password_1'];
    
        if (empty($username)) {
            array_push($errors, 'enter username');
        }
        if (empty($password_1)) {
            array_push($errors, 'enter password');
        }
        if (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {
            array_push($errors, 'username not correct');
            $username = "";
        }
    
        if (count($errors) == 0){      //The error is in this if condition
            $password = password_hash($password_1, PASSWORD_DEFAULT);
            $query = "SELECT * FROM users WHERE uidUsers=? AND pwdUsers=?";
            $stmt = mysqli_stmt_init($conn);
            mysqli_stmt_prepare($stmt, $query);
            mysqli_stmt_bind_param($stmt,'ss', $username, $password);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_store_result($stmt);
            $result = mysqli_stmt_num_rows($stmt);
            if (mysqli_num_rows($result) == 1){
                $_SESSION['uidUsers'] = $username;
                $idUsers_query = "SELECT idUsers FROM users WHERE uidUsers=? AND pwdUsers=?";
                $idUsers_stmt = mysqli_stmt_init($conn);
                mysqli_stmt_prepare($idUsers_stmt, $idUsers_query);
                mysqli_stmt_bind_param($idUsers_stmt,'ss', $username, $password);
                mysqli_stmt_execute($idUsers_stmt);
                mysqli_stmt_store_result($idUsers_stmt);
                $idUsers_result = $idUsers_stmt->get_result();
                $_SESSION['idUsers'] = $idUsers_result;
                $username = "";
                header("Location: https://...");
            }
            else{
                array_push($errors,'username or password not correct');
            }
        }
    }
    ?>

My Login system is not working because I don't get a Result or the right Result from my Database. Maybe it is because the Database doesn't accept "mysqli_stmt_store_result()" but I it is not possible to look up if mysqlnd is turned on (my provider has no option to change that). So is there a mistake in my code or is there a database problem?

  • 3
    In queries like this you do not rehash the password and you do not say `WHERE password = ?` You select the password and use `password_verify()` to make sure the password is correct. – Jay Blanchard Sep 02 '20 at 18:09
  • Use just the username/uidUsers as an input parameter in the sql and fetch the password as the result. Check that password using `password_verify` – Professor Abronsius Sep 02 '20 at 18:10
  • **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, and there are [authentication libraries](http://phprbac.net/) you can use. – tadman Sep 02 '20 at 19:27
  • Note: The [object-oriented interface to `mysqli`](https://www.php.net/manual/en/mysqli.quickstart.connections.php) is significantly less verbose, making code easier to read and audit, and is not easily confused with the obsolete `mysql_query` interface where missing a single `i` can cause trouble. Example: `$db = new mysqli(…)` and `$db->prepare("…")` The procedural interface is an artifact from the PHP 4 era and should not be used in new code. Additionally the procedural interface has less rigorous error checking and reporting, frustrating debugging efforts. – tadman Sep 02 '20 at 19:28

1 Answers1

1

You shouldn't do this:

$password = password_hash($password_1, PASSWORD_DEFAULT);
$query = "SELECT * FROM users WHERE uidUsers=? AND pwdUsers=?";

password_hash() won't produce the same hash every time you run it.

You should run the query on the uid, retrieve the password, and use password_verify() on it.

I don't use mysqli so I'm not best placed on the various options with that. When you echo various debug points through the code, how far does it get?

You do seem to run the same query twice, and the first time you are using $idUsers_stmt when binding parameters despite it not existing at that point. That will stop things working, I would imagine, but you can debug that quite easily.

droopsnoot
  • 931
  • 1
  • 7
  • 11
  • if (mysqli_num_rows($result) == 1){ // after this condition the code skip into the else-condition every time even the password is right. –  Sep 02 '20 at 18:17
  • That means that the number of rows is not one, it is something else, either zero (because it couldn't match the password, because you must use `password_verify()`, not do it the way you are doing it) or null (because of the errors in your query). – droopsnoot Sep 02 '20 at 18:28