Password_verify not matching even if the passwords are correct

Passwords doesn’t match, I keep getting the else statement “wrong email or password”.

I used $hash = password_hash($password, PASSWORD_DEFAULT) when user register on the register page.

Here is the login script

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


if(isset($_POST['loginSubmit'])){

	$stmt= $db->prepare("SELECT `email`,`password`,`status` FROM `reg_db` WHERE email=?");

	$stmt ->bind_param('s',$_POST['email']);

	$stmt->execute();

	$result = $stmt->get_result();

	while($user = $result->fetch_object()) {

		$email_row = $user->email;
		$password_hash = $user->password;         
		$status_row = $user->status;
        
        
		if(password_verify($_POST['password'], $password_hash)){    
			if($status_row  == 1 ) {
				$email_row = $_SESSION['email'];
				header("Location:index.php"); 
				exit();

			} else{ 
				header("Location:login.php?err=" . urlencode("The user account is not activated!"));
				exit();
			}
		} else {
			header("Location:login.php?err=" . urlencode("Wrong Email or Password!"));
			exit(); 

		}
	}
}


?>

The password column in the database are 255 varchar and the prepared statement does work, I can echo out all the selected variables.

I don’t know what I’m doing wrong.
Any suggestions will be helpful.
Thank you

There is a slicker way to do this if you are interested. You can download the code here. https://a1websitepro.com/login-script-with-ajax-jquery-php-and-mysql/

<?php session_start(); ?>
<!DOCTYPE html>
<html>
<head>
<title>Login Script with AJAX jQuery PHP and MySql</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<input id="username" type="text" placeholder="Username">
<input id="pass" type="password" placeholder="Password">
<input id="submit" type="button" value="Log In">
<div id="display"></div>
<script>
$(document).ready(function(){
$("#submit").click(function(){
var uname = $("#username").val();
var pass = $("#pass").val();
var dataString = 'uname1='+ uname + '&pass1='+ pass;
if(uname==''||pass=='')
{
$("#display").html("Please Fill All Fields");
}
else
{
$.ajax({
type: "POST",
url: "processor.php",
data: dataString,
cache: false,
success: function(result){
$("#display").html(result);
}
});
}
return false;
});
});
</script>
</body>
</html>

Then the PHP script.

<?php session_start();
include_once('config.php');
$name=mysqli_real_escape_string($con, $_POST['uname1']);
$nameclean = filter_var($name, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
$pass=mysqli_real_escape_string($con, $_POST['pass1']);
$passclean = filter_var($pass, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
$result = $con->query("SELECT * FROM users WHERE username='$nameclean' ") ;
$total=$result->num_rows;
if($total<1){
echo 'That user is not in our system';
}else{
while ($row = $result->fetch_assoc()) {
echo 'Yes we have a match and the email is '.$row['email'];
if(password_verify($passclean, $row['password'])){
	 $_SESSION['id']=$row['id'];
	echo '<br/>The Session ID is '.$_SESSION['id'];
}else{
	echo 'Wrong Password';
}
}
}
$con->close();
?>

Let’s be civil here.

@michelleh, are you storing your passwords as plain text or hashed? Because I just tested your code with minimal modifications and it worked as expected.

password_hash typically uses $2y$ as the beginning part of the hashed password. If your passwords don’t start like this, I would recommend that you start hashing your passwords correctly before inserting them.


@maximusmccullough29
sha and md5 are low level hashing algorithms and are obsolete. The OP is using a much much more secure hashing algorithm.

3 Likes

Much appreciated the update there. I guess I am just too old, lol.

Just remember to update yourself. Technology is always changing and if you want to be a good developer, you must adapt to change.

Amen to that my friend :slight_smile:

Tutorial has been updated and more secure password storage implemented. :slight_smile: have a good night

1 Like

This is totally wrong! Why would you filter the password in this way? If I want my password to be <a>verynice<dog> or use some other special characters you disallow that? If you want to force a password policy then tell the users on the site which characters are allowed/disallowed and then implement that in php. In the code above you are stripping content in a way that a normal user would not understand and might be up for an unpleasant surprise.

3 Likes

@spaceshiptrooper Yes I used hashing, my password in the database start with $2y$, but I keep getting the same error

Very true. Thanks for the heads up on that.

Update so that the password string is not sanatized

<?php session_start();
include_once('config.php');
$name=mysqli_real_escape_string($con, $_POST['uname1']);
$nameclean = filter_var($name, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
$pass=mysqli_real_escape_string($con, $_POST['pass1']);
$result = $con->query("SELECT * FROM users WHERE username='$nameclean' ") ;
$total=$result->num_rows;
if($total<1){
echo 'That user is not in our system';
}else{
while ($row = $result->fetch_assoc()) {
echo 'Yes we have a match and the email is '.$row['email'];
if(password_verify($pass, $row['password'])){
 $_SESSION['id']=$row['id'];
 echo '<br/>The Session ID is '.$_SESSION['id'];
}else{
 echo 'Wrong Password';
}
}
}
$con->close();
?>
1 Like

Can we see the form HTML?

2 Likes

Sure thing, here it is.

<?php session_start(); ?>
<!DOCTYPE html>
<html>
<head>
<title>Login Script with AJAX jQuery PHP and MySql</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<form>
<input id="username" type="text" placeholder="Username">
<input id="pass" type="password" placeholder="Password">
<input id="submit" type="button" value="Log In">
</form>
<div id="display"></div>
<script>
$(document).ready(function(){
$("#submit").click(function(){
var uname = $("#username").val();
var pass = $("#pass").val();
var dataString = 'uname1='+ uname + '&pass1='+ pass;
if(uname==''||pass=='')
{
$("#display").html("Please Fill All Fields");
}
else
{
$.ajax({
type: "POST",
url: "processor.php",
data: dataString,
cache: false,
success: function(result){
$("#display").html(result);
}
});
}
return false;
});
});
</script>
</body>
</html>

As @droopsnoot has mentioned, we need to see your HTML.

@maximusmccullough29, droopsnoot was talking to the OP.

1 Like

Sorry for the confusion. Have a great day! :slight_smile:

            <div class="login">
                <div class="container">
                    <div class="row">
                        <div class="col-md-4 col-md-offset-4">
                            <form class="form-horizontal" method="post" action="login.php">
                                <div class="form-group">
                                    <h2>Login</h2>
                                    <?php if(isset($_GET['success'])) { ?>
                                        <?php echo $_GET['success']; ?>
                                            <?php } ?>
                                                <?php if(isset($_GET['err'])) { ?>
                                                    <?php echo $_GET['err']; ?>
                                                        <?php } ?>
                                                            <label class="control-label col-sm-2" for="email">Email:</label>
                                                            <div class="col-10">
                                                                <input type="email" class="form-control" name="email" id="email" placeholder="Enter email" autocomplete="off" required=""> </div>
                                </div>
                                <div class="form-group">
                                    <label class="control-label col-sm-2" for="password">Password:</label>
                                    <div class="col-10">
                                        <input type="password" class="form-control" name="password" id="password" autocomplete="off" required="" placeholder="Enter password"> </div>
                                </div>
                                <div class="container">
                                    <div class="row">
                                        <div class="col-md-3 ">
                                            <div class="form-group">
                                                <button type="submit" name="loginSubmit" id="loginSubmit" class="btn btn-login">Login</button>
                                                <button type="button" onclick="location.href ='forgotPassword.php'" id="forget" class="btn btn-login">Forgot Password</button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>

Now, can you show us at least one row of data? Doesn’t have to be the complete exported table. Just 1 row that includes the password.

Is it correct that these lines try to do a redirect to login.php, which I understand is the name of the PHP code that’s trying to do the redirect?

header("Location:login.php?err=" . urlencode("The user account is not activated!"));
... and ...
header("Location:login.php?err=" . urlencode("Wrong Email or Password!"));

Might not be relevant, I just wondered if it might be redirecting twice, though that would presumably do something different - fail if if isset() check for a start.

If status is 0 then the page redirects to:

header("Location:login.php?err=" . urlencode("The user account is not activated!"));

If password doesn’t match then page redirect to:

header("Location:login.php?err=" . urlencode("Wrong Email or Password!"));

But surely login.php is that PHP code that is doing the redirect? That’s the destination of your form post. So when it redirects, it just redirects to itself, and has no $_POST array any more. Or am I mixing the names up?

<form class="form-horizontal" method="post" action="login.php">