Please fellow Devs, i just created a Signup(Registration) Portal in PHP using password Hash to store my password in the Database, but i cannot Login to the welcome page because the password passed from the login page is not the same as the Hashed password in the database.
Here is the code below:
someone should please tell me whats wrong, thanks.
FORM
<?php
include_once('../public/header.php');
include('../validate/login.php');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../public/styles/style.css">
<title>student login</title>
</head>
<body>
<div class="container ml-lg-5 mr-lg-5">
<div class="row ml-lg-5 mr-lg-5 p-lg-5">
<div class="col ml-lg-5 mr-lg-5 p-lg-5 shadow">
<form action="" method="POST">
<div class="text-danger"><?php echo $err_msg ?></div>
<label for="regno">Reg No</label>
<input type="text" name="regno" class="form-control">
<div class="text-danger"><?php echo $regno_err ?></div>
<label for="password">Password</label>
<input type="password" name="password" class="form-control">
<div class="text-danger"><?php echo $password_err ?></div>
<input type="submit" value="LOGIN" class="btn btn-outline-primary">
</form>
</div>
</div>
</div>
</body>
</html>
FORM VALIDATION CODE
<?php
$err_msg = $regno_err= $password_err= "";
if($_SERVER["REQUEST_METHOD"] == "POST"){
if ( !isset($_POST['regno'], $_POST['password']) ) {
// Could not get the data that should have been sent.
$err_msg='Please fill both the username and password fields!';
};
if(empty(trim($_POST['regno']))){
$regno_err="please fill in regno";
}elseif ($stmt = $conn->prepare('SELECT * FROM user WHERE regno = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$stmt->bind_param('s', $_POST['regno']);
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
if($stmt->num_rows == "false"){
$regno_err= "user does not exist";
}else{
$regno=$_POST['regno'];
$sql = "SELECT * From user WHERE regno = '{$regno}' ";
$query = mysqli_query($conn, $sql);
if(!$query){
die('unable to query'.$conn->error);
}
while($row = mysqli_fetch_array($query)) {
$id = $row['id'];
$username = $row['username'];
$regno_in =$row['regno'];
$email = $row['email'];
$department = $row['department'];
$pass_word = $row['password'];
}
$password=password_verify($pass_word,$_POST['password']);
if($regno_in ==$regno && $pass_word == $password){
echo "you are welcome";
$_SESSION['password'] = $pass_word;
echo "your email is:".$_SESSION['password'];
}else{
echo "password does not match db";
}
}
$stmt->close();
}
}$conn->close();
?>
Top comments (5)
Quick Tip - Add the #help tag to posts where you need a hand with things, that way people who are looking to help will be on hand!
Possible cause
On the line
$password=password_verify($pass_word,$_POST['password']);
What you are doing is instructing the system to check that the post variable "password" should be hashed and then check if it matches
$pass_word
- your hashed variable.password_verify
returns aboolean
(true
/false
) which (hopefully) should returntrue
in this instance.In the line below that you try and compare
$password
(true
orfalse
) to$pass_word
(A hashed password value).So if you change the line to
if($regno_in ==$regno && $password == true){
You should get a successful login (assuming you have done everything else correctly as in your question you said the hashes did not match, but I cannot tell if that is from something you
echo
ed out or just because you couldn't log in).Couple of observations just to be aware of
Just a few things to consider as you are learning so you don't develop bad habits which you later have to unlearn.
Be careful with queries and user input - you used bound variables in your first query so that should be pretty safe (but you should still sanitise it - rule one is never trust user input!) but in your second query you just pass the
$_POST
parameter straight to the query which is dangerous as a user can send anything they want in that$_POST
parameter. Also you don't need to query twice, you already have the query results from your first query as it is identical so remove the second query.Possible issue with duplicate entries - you should check that your query only returns 1 result before grabbing the information and return an error if you return more than one row. If 2 people had the same
regNo
due to a mistake you would always grab the second personsregNo
because you use awhile
loop and overwrite the values. Or you can just make theregNo
field unique entries only (which you may already have done) to avoid this."user does not exist" allows people to guess
regNo
- It is not a good practice to have "user does not exist" echoed out - that may just be for testing purposes (which is fine), but in production that lets an attacker know when they have successfully guessed a correctregNo
so they can brute force attack more easily. Instead just return "incorrect username or password" in production.Don't store the password hash in a session - Finally I would recommend not storing the password itself as a session variable, it could open up an attack vector (although this is not a huge concern compared to the other things mentioned as session variables are pretty secure). As sessions are per user and managed by the server you can just save that they are authenticated.
In addition, this line is vulnerable to an SQL Injection:
That was the bit I meant with point 1 but it obviously wasn't clear, thanks for pointing it out! ❤
thank you all, your advice really helped me
thanks alot sir, your advice helped me alot.
am grateful, i will try my best to implement all that you have recommended me to adhere to.