So I have a Registration page and a Login page, the registration page works perfectly fine but the Login page doesnt seem to work and I cant seem to figure it out.
My database seems to be working as I am able to echo out the hashed password onto the page of the login, it seems to have something to do with password_verify()
Registration Page (Working)
<?php
include("assets/includes/conn.php");
$user = $_POST['username'];
$pass = $_POST['pass'];
$cPass = $_POST['c-pass'];
$email = $_POST['email'];
$options = [
'cost' => 11
];
if($pass == $cPass){
$stmt = $conn->prepare("INSERT INTO users (username, pass, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $user, $h_p, $email);
$user = $_POST['username'];
$h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
$email = $_POST['email'];
$stmt->execute();
echo "Created";
echo $h_p;
$stmt->close();
$conn->close();
}
Login Page (Not working)
<?php
include("assets/includes/conn.php");
$username = $_POST['username'];
$password = $_POST['pass'];
$sql = "SELECT * FROM users WHERE username = '$username'";
$result = $conn->query($sql);
if ($result->num_rows == 1){
$row = $result->fetch_assoc();
$hash = $row['pass'];
if(password_verify($password, $hash)){
echo "Yes";
} else {
echo "No<br/>";
echo "" . $hash . "<br/>";
echo $password;
}
}
The problem here is that the \n
in:
$h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
^^
is (invisibly) adding a carriage return/linefeed at the end of your password/hash.
You can either remove it.
$h_p = password_hash($pass, PASSWORD_DEFAULT, $options);
or trim()
it:
$h_p = password_hash($pass, PASSWORD_DEFAULT, $options)."\n";
$h_p = trim($h_p);
I honestly don't know why the manual on password_hash()
doesn't make a mention about it and the usage of it for storing it in a database (or a file).
NOTE: What the docs haven't used here, was to assign a variable to the example, which is what was done in the question here. Some may think that using the example and assigning a variable to it will work; it won't; not for storing the hash and then verifying it after.
The example from the manual reads as:
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
But doing:
$var = password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
will in fact (theoretically) contain a 61-length string (because of the concated linefeed character), instead of the intended 60 without the linefeed character.
Have a look at this sandbox code example
When run, it will output something like this:
$2y$10$494GPYzaynEkfYxE3wcAj.OtwBU3CCwTMXOHKbdJmOqwMXRmq6v1u 61
Just in case the URL's a 404 later on, here's the code for the above:
<?php
$foo = password_hash('mypass', PASSWORD_DEFAULT)."\n";
echo $foo;
echo strlen($foo);
On an added note; you should also use a prepared statement for your SELECT
just as you did for the INSERT
; it's much safer.