Why Password_Verify Function Not Logging Me In ?

Status
Not open for further replies.

sunny_pro

New member
Joined
Jun 18, 2017
Messages
86
Points
0
Php Programmers,


It fails to log me in to my account with the correct Username/Email and Password.
Do check the script on your end in Xampp/Wamp.
Why is the password_verify failing on this script ? Did I get it wrong ?

Thank You!

Code:
<?php
 
/*
ERROR HANDLING
*/
declare(strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
 
include 'config.php';
 
// check if user is already logged in
if (is_logged() === true) 
{
	//Redirect user to homepage page after 5 seconds.
	header("refresh:2;url=home.php");
	exit; //
}


if ($_SERVER['REQUEST_METHOD'] == "POST")
{ 
	if (isset($_POST["login_username_or_email"]) && isset($_POST["login_password"]))
	{
		$username_or_email = trim($_POST["login_username_or_email"]); //
		$password = $_POST["login_password"];
		$hashed_password = password_hash($password, PASSWORD_DEFAULT);
         
		//Select Username or Email to check against Mysql DB if they are already registered or not.
		$stmt = mysqli_stmt_init($conn);
		
        if(strpos("$username_or_email", "@") === true)
		{
			$email = $username_or_email;
			$username = "";
			
			$query = "SELECT ids, usernames, passwords, emails, accounts_activations_statuses FROM users WHERE emails = ?";
			// i = integer; s = string; d = double; b = blob.
			mysqli_stmt_init($stmt);
			$stmt = mysqli_prepare($conn, $query);			
			mysqli_stmt_bind_param($stmt, 's', $email);
			mysqli_stmt_execute($stmt);
		    $result = mysqli_stmt_bind_result($stmt, $db_id, $db_username, $db_password, $db_email, $db_account_activation_status); // ... this line. But not both.
		}
		else
		{
			$username = $username_or_email;
			$email = "";
			$query = "SELECT ids, usernames, passwords, emails, accounts_activations_statuses FROM users WHERE usernames = ?";
			$stmt = mysqli_prepare($conn, $query);
			mysqli_stmt_bind_param($stmt, 's', $username);
			mysqli_stmt_execute($stmt);
			$result = mysqli_stmt_bind_result($stmt, $db_id, $db_username, $db_password, $db_email, $db_account_activation_status); // ... this line. But not both.#
		}       	
		
		//QUESTION: Which one of the following 3 to do and why that one over the other 2 ?
		$row = mysqli_stmt_fetch($stmt);
		//$row = mysqli_fetch_array($query, MYSQLI_ASSOC);
		//$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
		
		mysqli_stmt_close($stmt);
		
		printf("%s (%s)\n",$row["usernames"],$row["passwords"]);
		echo "var_dump(row)";var_dump($row);?><br><?php //On test, this showing as: () bool(true);
		echo "var_dump(result)";var_dump($result)?><br><?php //On test, this showing as: () bool(true);
		
		if ($result == false)
		{
			echo "Incorrect User Credentials 1 - (query result == FALSE on LINE 79! )!<br>";
			echo "Id from db: $db_id<br>";
			echo "Email from db: $db_email<br>";
			echo "Username from db: $db_username<br>";
			echo "Hash from db: $db_password<br>";
			echo "Account Activation Status from db: $db_account_activation_status<br>";
			exit(); 
		}
		elseif ($row['accounts_activations_statuses'] == '0')
		{
			{
				echo "You have not activated your account yet! Check your email for instructions on how to activate it. 
				Check your spam folder if you don't find an email from us.";
				exit();
			}
		}
		else
		{
			echo "Else got triggered on LINE 98! - (query result = TRUE)!<br>";//This ELSE is getting triggered on the test. That means $result = TRUE;
			echo "Id from db: $db_id<br>";
			echo "Email from db: $db_email<br>";
			echo "Username from db: $db_username<br>";
			echo "Hash from db: $db_password<br>";
			echo "Account Activation Status from db: $db_account_activation_status<br>";
		}
		
		if (password_verify($password, (string)$row['passwords'])==true)
		{
			//If 'Remember Me' check box is checked then set the cookie. 
			if(!empty($_POST["login_remember"])) // Either use this line ....
			//if (isset($_POST['login_remember']) && $_post['login_remember'] == "on") // ...or this line. But not both!
			{
				setcookie("login_username", $username, time()+ (10*365*24*60*60));
			}
			else
			{
				//If Cookie is available then use it to auto log user into his/her account!
				if (isset($_COOKIE['login_username']))
				{
					setcookie("login_username","","");
				}
			}
			$_SESSION["user"] = $username;
			header("location:home.php?user=$username");				
		}
		else
		{
			echo "Incorrect User Credentials 2! (Else got triggered on LINE 124. Stating: 'password_verify = FALSE');<br>";
			echo "Id from db: $db_id<br>";
			echo "Email from db: $db_email<br>";
			echo "Username from db: $db_username<br>";
			echo "Hash from db: $db_password<br>";
			echo "Account Activation Status from db: $db_account_activation_status<br>";
			exit();
		}
	}
}
	
?>

<!DOCTYPE html>
<html>
<head>
<title><?php $site_name?> Member Login Page</title>
  <meta charset="utf-8">
</head>
<body>
<div class = "container">
<form method="post" action="">
<center><h3><?php $site_name ?> Member Login Form</h3></center>
<div class="text-danger">
<div class="form-group">
<center><label>Username/Email:</label>
<input type="text" placeholder="Enter Username" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center>
</div>
<div class="form-group">
<center><label>Password:</label>
<input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center>
</div>
<div class="form-group">
<center><label>Remember Login Details:</label>
<input type="checkbox" name="login_remember" /></center>
</div>
<div class="form-group">
<center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center>
</div>
<div class="form-group">
<center><font color="red" size="3"><b>Forgot your password ?</b><br><a href="login_password_reset.php">Reset it here!</a></font></center>
<center><font color="red" size="3"><b>Not registered ?</b><br><a href="register.php">Register here!</a></font></center>
</form>
</div>
</body>
</html>
It fails to log me in with the correct password. Column name: passwords. And not "password" or "Password" or "Passwords" as some might suspect I done a typo in column name when I have not.
 

Rob Whisonant

Moderator
Joined
May 24, 2016
Messages
2,489
Points
113
Post a formatted copy of the php code. Nobody is going to want to try to read that.

I usually input code inbetween these tags:

PHP:
Code:
Which tags this forum uses ?
You are using the correct tags. What you posted is not formatted with line feed/carriage return pairs though. Most likely the text editor you are cutting and pasting from.
 

Rob Whisonant

Moderator
Joined
May 24, 2016
Messages
2,489
Points
113
Are you using password_verify properly? Is the hash stored in the database and not the raw password? password_verify compares the password to the hashed version.

you can also simplify that line and remove the (string) and ==true portions. For example.

if (password_verify($password_user_entered, $hash_password_stored_in_database)) {
echo "True";
}
 

sunny_pro

New member
Joined
Jun 18, 2017
Messages
86
Points
0
Rob Mod,


I added the (string) to Type Cast the 2nd param of password_verify due to receiving this error:

Fatal error: Uncaught TypeError: password_verify() expects parameter 2 to be string, null given in /home/user/public_html/php/login.php:97 Stack trace: #0 /home/user/public_html/php/login.php(97): password_verify('password123', NULL) #1 {main} thrown in /home/user/public_html/php/login.php on line 97


After I Type Casted then this error disappeared.

The following code is in this format:

Code:
if (password_verify($password, ($row['passwords'])))
		{
Code:
if (password_verify($USER ENTERED PASS, (PASS IN ROW OF DB))
		{
And so, it should work. Right ?
 

Rob Whisonant

Moderator
Joined
May 24, 2016
Messages
2,489
Points
113
The error you received before typecasting points to the problem. When you retrieve the hashed password from the database it's returning NULL. Check your sql syntax and add some error checking. Maybe echo the returned result so you can see if the hash is being returned.

Also read the manual on mysqli_stmt_fetch when using it with mysqli_stmt_bind_result to read the results.
 

sunny_pro

New member
Joined
Jun 18, 2017
Messages
86
Points
0
sunny_pro

Thanks! Sorry for the late reply. Was ill. Plus, was having internet connection problem. I will try your given link after I wakeup. Way past my bed time now. Someone suggested I raise the "passwords" column size to more than 50 digit and another agreed to him by saying to raise it to the max a hash could be. I want your advice. How many digits should I change it to ? How many digits you usually have for your hash password column ?


Thanks.
 

sunny_pro

New member
Joined
Jun 18, 2017
Messages
86
Points
0
Rob Whisonant!

You are the only other person and forum who rightfully figured I screwed things up at the column size!
I am just reading your suggestion to raise the size of my column where the hashed passwords would be populated.
Thank you for your help.
It seems the issue was the "passwords" column size was too small (50 chars). Switching it to 255 should have made a difference but it did not in my test last night due to me not repopulating the column. Others in another forum suggested I repopulate and I read their suggestion just now and it is working after I repopulated it. Just sharing this knowledge on all forums I opened threads on this issue so it benefits other newbies too. I know this is nothing "learnable" for pros.
webdeveloperDOTCOM/forum/showthread.php?366069-Why-password_verify-Not-Passing-The-Verification&p=1516863#post1516863

And so, this code is no longer getting the password_verify to false when I type the correct password.
Code:
Code:
<?php
 
/*
ERROR HANDLING
*/
declare(strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
 
include 'config.php';
 
// check if user is already logged in
if (is_logged() === true) 
{
	//Redirect user to homepage page after 5 seconds.
	header("refresh:2;url=home.php");
	exit; //
}


if ($_SERVER['REQUEST_METHOD'] == "POST")
{ 
	if (isset($_POST["login_username_or_email"]) && isset($_POST["login_password"]))
	{
		$username_or_email = trim($_POST["login_username_or_email"]); //
		$password = $_POST["login_password"];
		
         
		//Select Username or Email to check against Mysql DB if they are already registered or not.
		$stmt = mysqli_stmt_init($conn);
		
        if(strpos("$username_or_email", "@") === true)
		{
			$email = $username_or_email;
			$username = "";
			
			$query = "SELECT ids, usernames, passwords, emails, accounts_activations_statuses FROM users WHERE emails = ?";
			// i = integer; s = string; d = double; b = blob.
			$stmt = mysqli_prepare($conn, $query);			
			mysqli_stmt_bind_param($stmt, 's', $email);
			mysqli_stmt_execute($stmt);
		    //$result = mysqli_stmt_get_result($stmt); //Use either this line (if you need to get all data of the array without associating them to variables like you do with mysqli_stmt_bind_result), or ...
			//Note from line below that the variables "$db_username", "$db_account_activation_status" are related to the tbl columns selected on $query ("SELECT ids, usernames, accounts_activations_statuses From users .. WHERE).
			$result = mysqli_stmt_bind_result($stmt, $db_id, $db_username, $db_password, $db_email, $db_account_activation_status); // ... this line. But not both.
		}
		else
		{
			$username = $username_or_email;
			$email = "";
			$query = "SELECT ids, usernames, passwords, emails, accounts_activations_statuses FROM users WHERE usernames = ?";
			// i = integer; s = string; d = double; b = blob.
			$stmt = mysqli_prepare($conn, $query);
			mysqli_stmt_bind_param($stmt, 's', $username);
			mysqli_stmt_execute($stmt);
			//$result = mysqli_stmt_get_result($stmt); //Use either this line (if you need to get all data of the array without associating them to variables like you do with mysqli_stmt_bind_result), or ...
			//Note from line below that the variables "$db_email", "$db_account_activation_status" are related to the tbl columns selected on $query ("SELECT ids, emails, accounts_activations_statuses From users .. WHERE).
			$result = mysqli_stmt_bind_result($stmt, $db_id, $db_username, $db_password, $db_email, $db_account_activation_status); // ... this line. But not both.#
		}       	
		
		//$rownums = mysqli_num_rows($result); // To get number of row matches
		//echo "$rownums";
		//Which of the following to do and why that one over others ?
		$row = mysqli_stmt_fetch($stmt);
		//$row = mysqli_fetch_array($query, MYSQLI_ASSOC);
		//$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
		
		mysqli_stmt_close($stmt);
		
		printf("%s (%s)\n",$row["usernames"],$row["passwords"]);
		
		if ($result == false)
		{
			echo "'$result == false' on line 73! IF got triggered on line 73! !<br>";
			exit();
		}
		elseif ($row['accounts_activations_statuses'] == '0')
		{
			{
				echo "You have not activated your account yet! Check your email for instructions on how to activate it. 
				Check your spam folder if you don't find an email from us.";
				exit();
			}
		}
		else
		{
			echo "'$result == true' on line 73! Else got triggered on line 86! <br>";//This ELSE is getting triggered on the test. That means $result = TRUE;
		}
		
		if (password_verify($password, $db_password))		
		{
			echo "IF triggered for password_verify! password_verify ok";
			//If 'Remember Me' check box is checked then set the cookie. 
			//if(!empty($_POST["login_remember"])) // Either use this line ....
			if (isset($_POST['login_remember']) && $_post['login_remember'] == "on") // ...or this line. But not both!
			{
				setcookie("login_username", $username, time()+ (10*365*24*60*60));
			}
			else
			{
				//If Cookie is available then use it to auto log user into his/her account!
				if (isset($_COOKIE['login_username']))
				{
					setcookie("login_username","","");
				}
			}
			$_SESSION["user"] = $username;
			header("location:home.php?user=$username");				
		}
		else
		{
			echo "Else got triggered on line 111: Incorrect User Credentials ! 'password_verify = FALSE';<br>";
			exit();
		}
	}
}
	
?>

<!DOCTYPE html>
<html>
<head>
<title><?php $site_name?> Member Login Page</title>
  <meta charset="utf-8">
</head>
<body>
<div class = "container">
<form method="post" action="">
<center><h3><?php $site_name ?> Member Login Form</h3></center>
<div class="text-danger">
<div class="form-group">
<center><label>Username/Email:</label>
<input type="text" placeholder="Enter Username" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center>
</div>
<div class="form-group">
<center><label>Password:</label>
<input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center>
</div>
<div class="form-group">
<center><label>Remember Login Details:</label>
<input type="checkbox" name="login_remember" /></center>
</div>
<div class="form-group">
<center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center>
</div>
<div class="form-group">
<center><font color="red" size="3"><b>Forgot your password ?</b><br><a href="login_password_reset.php">Reset it here!</a></font></center>
<center><font color="red" size="3"><b>Not registered ?</b><br><a href="register.php">Register here!</a></font></center>
</form>
</div>
</body>
</html>
I am making a few changes on the above post's mentioned code because I was told in that forum (which I mentioned in my previous post):

1. Checking if $result is true/false is meaningless, as it will always be true if my code is bug-free, and likely always false if not.
2. Similarly, mysqli_stmt_fetch() will return true if it found a result row, otherwise false.
I, instead need to check the value bound to $db_password to see if it's correct. So it might be something like:

Code:
if($row && password_verify($password, $db_password)) {
// good to go...
}
I have been advised 6 nights ago there on that forum to trim down my code to this:
Code:
if ($_SERVER['REQUEST_METHOD'] == "POST") // not really needed since you're checking $_POST
{
    if (isset($_POST["login_username"]) && isset($_POST["login_password"])) {
        $username = trim($_POST["login_username"]); //
        $password = trim($_POST["login_password"]); //
        $hashed_password = password_hash($_POST["login_password"], PASSWORD_DEFAULT);
        $sql = "
SELECT
  ids,
  usernames, 
  passwords, 
  emails, 
  accounts_activations_statuses 
FROM users 
WHERE usernames = ?
  AND passwords = ?
";
        $stmt = mysqli_prepare($conn, $sql);
        mysqli_stmt_bind_param($stmt, 'ss', $username, $hashed_password);
        mysqli_stmt_execute($stmt);
        if (mysqli_stmt_num_rows($stmt)) {
            // found a match, we're good to go...
        } else {
            // whatever you do when user/password not found...
        }
    }
}
 
Status
Not open for further replies.
Latest threads
Replies
0
Views
35
Replies
0
Views
35
Replies
1
Views
47
Replies
3
Views
111
Recommended threads
Replies
2
Views
2,784
Replies
0
Views
6,102
Replies
3
Views
2,300
Replies
6
Views
7,429
Replies
4
Views
5,523
Top