Where to put password_verify in login script?
Before you read the code, keep in mind that the Fake Registration
block would not be in your code, but it is necessary to show you this, end-to-end.
<?php
session_start();
// Begin Vault
// credentials from a secure Vault, not hard-coded
$servername="localhost";
$dbname="login_system";
$username="dbUserName";
$password="dbPassword";
// End Vault
// The following two variables would come from your form, naturally
// as $_POST[]
$formEmail="[email protected]";
$ctPassword="¿^?fish╔&®)"; // clear text password
try {
#if(isset($_POST['email'], $_POST['password'])){
#require('../../../private_html/db_connection/connection.php');
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Begin Fake Registration
// fake it that user already had password set (from some registration insert routine)
// the registration routine had SSL/TLS, safely passing bound parameters.
$hp=password_hash($ctPassword,PASSWORD_DEFAULT); // hashed password, using
$conn->query("delete from user_accounts where email='[email protected]'");
$conn->query("insert user_accounts(first_name,last_name,email,password) values ('joe','smith','[email protected]','$hp')");
// we are done assuming we had a registration for somewhere in your system
// End Fake Registration
$query = $conn->prepare("SELECT * FROM user_accounts WHERE email=:email");
$query->bindParam(':email', $formEmail);
$query->execute();
unset($_SESSION['email']);
unset($_SESSION['first_name']);
if(($row = $query->fetch()) && (password_verify($ctPassword,$row['password']))){
$_SESSION['email'] = $row['email'];
$_SESSION['first_name'] = $row['first_name'];
//header("Location: ../../myaccount/myaccount.php");
echo "hurray, you authenticated.<br/>";
}
else {
//header("Location:../../login/login.php ");
echo "invalid login<br/>";
}
#}
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit();
}
?>
Browser Output:
hurray, you authenticated.
Note, the password_hash()
function utilizes a random salt, as is evident
if you run it several times, with the hashed password changing with same clearText input, such as these hashed passwords:
$2y$10$KywNHrGiPaK9JaWvOrc8UORdT8UXe60I2Yvj86NGzdUH1uLITJv/q
$2y$10$vgJnAluvhfdwerIX3pAJ0u2UKi3J.pfvd0vIqAwL0Pjr/A0AVwatW
both of which are the result of subsequent hashings, as mentioned, of the same clear text password. The salt
and hash cost
are baked into the hashed password and saved. These call all be read about in links below.
From the Manual password_hash and password_verify.
Schema
create table user_accounts
( id int auto_increment primary key,
first_name varchar(50) not null,
last_name varchar(50) not null,
email varchar(100) not null,
password varchar(255) not null
);