Jump to content

Login with password_verify() fail all time


Go to solution Solved by Jacques1,

Recommended Posts

Hi, i have problem with login script. Problem is that i cant login using my username and password. Password i entered in database was with password_hash('admin', PASSWORD_DEFAULT);

 

Here is a code

<?php
include 'config.php';

if (isset($_SESSION['laa']))
{
	die('U already logged in. <a href="index.php">Home</a>');
}

if (isset($_POST['login']))
{
	if (isset($_POST['username']) && isset($_POST['password']))
	{
		$username = strip_tags($_POST['username']);
		$password = strip_tags($_POST['password']);

		if (empty($username) || empty($password))
		{
			$error = 'Please enter username and password.';
		}
		else
		{

			//$password = password_verify($password, PASSWORD_DEFAULT);

			$stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username AND lozinka = :password");
			$stmt->bindParam(':username', $username);
			$stmt->bindParam(':password', $password);
			$stmt->execute();
			$p = $stmt->fetch();

			//password_verify($password, $data['password']))

			if ($p['username'] == $username || $p['password'] == $password)
			{
				$_SESSION['laa'] = $username;
				header('Location: index.php');
				exit();
			}
			else
			{
				$error = 'Invalid username or password.';
			}
		}
	}
	else
	{
		$error = 'Please enter username and password.';
	}
}

?>
<center>
<div style="display:block; margin-top: 10%;">
	<p><?php if(!empty($error)) { echo $error; } ?></p>
	<form action="login.php" method="post">
	<p>Username : <input type="text" name="username"></p>
	<p>Password : <input type="password" name="password"></p>
	<p><input type="submit" name="login" value="Login"></p>
	</form>
</div>
</center>
  • Solution

First off, you need to get rid of this strip_tags() nonsense. This can in fact destroy your passwords, because it blindly removes anything that looks like HTML markup.

 

The password_verify() function works like this:

if (password_verify($the_password_to_be_checked, $the_stored_password_hash))
{
    // correct password
}
else
{
    // wrong password
}
  • Like 1

Thanks i used it like this and how works, also problem was in $p['password'] instead or $p['lozinka'] and same for username/korisnicko ime.

                        $stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username");
			$stmt->bindParam(':username', $username);
			$stmt->execute();
			$p = $stmt->fetch();

			if (password_verify($password, $p['lozinka']) || $p['korisnicko_ime'] == $username)
			{
				$_SESSION['laa'] = $username;
				header('Location: index.php');
				exit();
			}

Now you're doing an OR check, which means anybody can log-in without a password if they enter a valid username. You need an AND check (&&).

 

// Or rather: Leave out the username check altogether. It's already in the query.

Edited by Jacques1
  • Like 1

I try this, and it works, if u enter valid username it wont login if u enter valid password and invalid username it wont login. But if i leave WHERE korisnicko_ime = :username AND lozinka = :password this don't works.

			$stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username");
			$stmt->bindParam(':username', $username);
			$stmt->execute();
			$p = $stmt->fetch();

			if (password_verify($password, $p['lozinka']) && $p['korisnicko_ime'] == $username)
			{
				$_SESSION['laa'] = $username;
				header('Location: index.php');
				exit();
			}

Since the password validation happens on the PHP side, you don't need to include it in the query. The username also doesn't need to be validated on the PHP side since that is already done in the query. Unless I'm not thinking clearly...or maybe I missed something, this should be fine:

$stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username");
$stmt->bindParam(':username', $username);
$stmt->execute();
$p = $stmt->fetch();
 
if (password_verify($password, $p['lozinka']))
{
    $_SESSION['laa'] = $username;
    header('Location: index.php');
    exit;
}
Edited by cyberRobot

U thinking clearly :), if i select username from database it will give me all information about this user as i need, and what i need is to check if that password is valid for that username from query. So your code need to be valid.

 

I try to login with all combination and it only login me with right username and password. So this works. Thanks guys.

Edited by Mlaaa

Side note: since there should only be one entry with any given username, you could optimize the query using the LIMIT clause.

$stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username LIMIT 1");

That way MySQL stops looking for more records as soon as it finds the first match.

  • Like 1

Side note: since there should only be one entry with any given username, you could optimize the query using the LIMIT clause.

$stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username LIMIT 1");

That way MySQL stops looking for more records as soon as it finds the first match.

 

 

I would think that with a unique index, Mysql already knows there is only going to be one result.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.