-3

I'm trying to create a simple login using mySQLi with PHP. I have everything set up using a variable $username and $password that holds the login information rather than using post from a form as I just want to get it working first before advancing to this and injection protection. So all in all if the variables match the table in the data base then it prints Logged In! otherwise it'll print Invalid username or password but every time I run this I get an error:

Error:

Warning: mysqli_query() expects parameter 1 to be mysqli, null given

<?
    $dbhost = 'localhost';
    $dbuser = 'xxxx';
    $dbpass = 'xxxx';
    $dbname = 'xxxx';
    $con = mysqli_connect($dbhost, $dbuser, $dbpass,$dbname);

    $sql="SELECT email, pass FROM lg_user";

    $username = 'Admin';
    $password = "123qweQWE";

    $query = "SELECT `user` FROM `lg_user` WHERE `user`='$username' AND `pass`='$password'"; 
    var_dump($query);

        if($query_run = mysqli_query($conn,$query)){
            $query_num_rows = mysqli_num_rows($query_run);

            if($query_num_rows == 0){
                print("Invalid username or password");
            }
            else if($query_num_rows == 1){
                print("Logged In!");
            }
        }
?>
Dave Tops
  • 3
  • 2
  • Please check my answer, it will resolve your problem. You need to pass valid mysqli object. – Darshan Jain Mar 28 '18 at 08:24
  • [`mysql_close()`](http://php.net/manual/en/function.mysql-close.php) doesn't work with [`mysqli_*` functions](http://php.net/manual/en/class.mysqli.php). They belong to [different MySQL extensions](http://php.net/manual/en/mysql.php); the old MySQL extension is deprecated since PHP 5.5 and removed from PHP 7 completely. – axiac Mar 28 '18 at 08:27
  • SqlInjection issues, non-encrypted passwords etc... find a better tutorial. – ArtisticPhoenix Mar 28 '18 at 08:31
  • @ArtisticPhoenix If you read the post I've already mentioned that I'm not working to resolve this issues until I have a working system as what's the point in over complicating it until it works using this simplest components. – Dave Tops Mar 28 '18 at 08:40
  • 1
    this question should be closed and deleted, as it makes no sense – Your Common Sense Mar 28 '18 at 08:48
  • Because sometime the right way is not so hard or over complicated and if you have to re-write significant portions of it to do it the right way, then you are effectively doubling the work by not doing it the right way to begin with. – ArtisticPhoenix Mar 28 '18 at 15:52

1 Answers1

0

Just to make my point that doing it the right way is not over complicated here you go.

$dbhost = 'localhost';
$dbuser = 'xxxx';
$dbpass = 'xxxx';
$dbname = 'xxxx';

$Pdo = new PDO("mysql:host={$dbhost};dbname={$dbname};charset=utf8", $dbuser, $dbpass);

$Pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$Pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$Pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

$username = 'Admin';
$password = "123qweQWE";  //create a password with password_hash($password, PASSWORD_DEFAULT);

$stmt = $Pdo->prepare("SELECT `user`,`pass` FROM `lg_user` WHERE `user`=:username");  //don't pull user by looking for the password. 
$stmt->execute([':username' => $username]);

if($stmt->rowCount() == 1){
    $row = $stmt->fetch();
    if(password_verify($password, $row['pass'])){
        //verify does not require hashing the incoming password (assuming password was made with password_hash)
        print("Logged In!");
    }else{
        print("Invalid password");
    }
}else{
    print("Invalid username");
}

23 lines, 3 of which are optional ($Pdo->setAttribute). The original attempt 17 lines.

Both of these have at least 2 extra lines in (username/password canned data). So for 6 extra lines (3 of which are optional) We can do this the right way. Coincidentally the other 3 lines are here (separate error for password/username):

}else{
   print("Invalid password");
}

So pretty much the same number of lines.

Major notes,

  • Do not check password by querying it.
    • Hashes are case sensitive, DB typically is not (unless you use UTF8_bin).
    • It's not a cryptologically secure evaluation of the hash
    • You can't tell if it's a bad password or a bad username
  • Use prepared statements.
  • Use PHP's built in password functions
  • Use PDO,
    • the OOP API for PDO is better
    • the fetch modes are far better than mysqli
    • the error handling is far better (with exception mode)
    • all this saves a lot of work in the long run (my opinion).

References:

http://php.net/manual/en/function.password-verify.php

http://php.net/manual/en/function.password-hash.php

http://php.net/manual/en/class.pdo.php

I would also strongly recommend making the username a unique index in the Database itself. This will give you 100% guarantee that usernames cannot be duplicated. It will also throw an exception with PDO, which is very easy to catch and report.

ArtisticPhoenix
  • 21,464
  • 2
  • 24
  • 38