0

I'm new to PHP. I'm making a login form. Here's my html:

<form method="POST" id="login_form" action="log_in.php">
    <div class="form-group">
        <label for="Username">Username</label>
        <input autocomplete="off" type="text" class="form-control" id="username" required>

    </div>
    <div class="form-group">
        <label for="Password">Password</label>
        <input autocomplete="off" type="password" class="form-control" id="password" required>
    </div>
    <button type="submit" id="submit_login" class="btn">Log in</button>
</form>

Here's my log_in.php

<?php
include("db.php");


if ($_SERVER['REQUEST_METHOD']=='POST') {
    $username = $_POST["username"];
    $password = $_POST["password"];
    $stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND pass=?");
    $stmt->bind_param("ss", $username, $password);
    $stmt->execute();
    $result = $stmt->get_result();
    $check = mysqli_num_rows($result);
    if ($check > 0) {
        while ($row = $result->fetch_assoc()) {
            if ($username == $row['username'] && (password_verify($password, $row['pass']) || $password == $row['pass'])) {
                if ($row['stat'] == "Admin") {
                    $conn->close();
                    header("Location: admin.php");
                    break;
                } else {
                    $conn->close();
                    header("Location: member.php");
                    break;
                }
            }
        }
    }
}
else {
    echo "<script>";
    echo "alert('No Matching Records!');";
    echo "</script>";
}
?>

The problem is that I think the button does not submit the username and password to the server. i get an error Undefined index:username, and Undefined index:password. and it does not log in and load to the header destination. i cant find the problem. thank u in advance!

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
Echo
  • 521
  • 5
  • 16
  • 2
    Input fields need to have a `name` attribute. The browser uses the `name` attribute to build the GET or POST data. If the input fields does not have a `name=` attribute the field is ignored – RiggsFolly Mar 05 '20 at 14:35
  • 1
    Never put plain text passwords on your database, its a Huge security hole.. PHP provides [`password_hash()`](http://php.net/manual/en/function.password-hash.php) and [`password_verify()`](http://php.net/manual/en/function.password-verify.php) please use them for the safety of your users. – RiggsFolly Mar 05 '20 at 14:38
  • 2
    **BIG NOTE** Oh you are using `password_verify()` ?? In that case you cannot use the password in the WHERE on the query, because the user entered password will NEVER be the hashed password !! :) – RiggsFolly Mar 05 '20 at 14:40
  • Yeap, you need to pass `password_hash($_POST['password'], PASSWORD_DEFAULT);` to your query. (Or whatever hashing algorithm you're using) - I'll edit my answer to note this too. – Altherius Mar 05 '20 at 14:43
  • @Altherius ___Big Error Note___ you will NEVER get the same hash from `password_hash()` twice, even using the exact same password. So your above suggestion is not valid – RiggsFolly Mar 05 '20 at 14:49

1 Answers1

0

Add a name to your inputs :

<form method="POST" id="login_form" action="log_in.php">
    <div class="form-group">
        <label for="username">Username</label>
        <input autocomplete="off" type="text" class="form-control" id="username" name="username" required>

    </div>
    <div class="form-group">
        <label for="password">Password</label>
        <input autocomplete="off" type="password" class="form-control" id="password" name="password" required>
    </div>
    <button type="submit" id="submit_login" class="btn">Log in</button>
</form>

Also note that this

$stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND pass=?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();

Will never return anything if you hash your passwords in the database (I hope you do ?!). You should drop it from your query.

$stmt = $conn->prepare("SELECT * FROM users WHERE username=?");
$stmt->bind_param("s", $username);
$stmt->execute();

See password_hash documentation for more details.

Altherius
  • 754
  • 7
  • 23
  • Now why didn't I think of that :) – RiggsFolly Mar 05 '20 at 14:47
  • Altherius ___Big Error Note___ you will NEVER get the same hash from `password_hash()` twice, even using the exact same password. So your above suggestion to attempt to hash the incoming password so it matches the one on the database is not valid. You can only do the compare using `password_verify()` – RiggsFolly Mar 05 '20 at 14:50
  • Indeed, forgot about the salt. Better to simply drop it from the query I guess. Searching for duplicate passwords is a security issue anyway. Answer has been edited. And the password_verify is done further in the given code. – Altherius Mar 05 '20 at 14:54
  • @Altherius if i drop it from the query, how could i verify the password? – Echo Mar 06 '20 at 09:32
  • You should get the row (by the username only), and then you should use password_verify to compare the hashes. – Altherius Mar 06 '20 at 10:07