Vaak worstelen ontwikkelaars met de verificatie van een inlogwachtwoord, omdat ze niet zeker weten hoe ze met de opgeslagen wachtwoordhash moeten omgaan. Ze weten dat het wachtwoord gehasht moet worden met een geschikte functie zoals password_hash( )
, en sla ze op in een varchar(255)
veld:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
In het inlogformulier kunnen we het wachtwoord niet rechtstreeks verifiëren met SQL, noch kunnen we ernaar zoeken, omdat de opgeslagen hashes gezouten zijn. In plaats daarvan...
- moet de wachtwoord-hash uit de database lezen, zoekend op gebruikers-ID
- en daarna het inlogwachtwoord kunnen vergelijken met de gevonden hash met de password_verify() functie.
Hieronder vindt u een voorbeeldcode die laat zien hoe u wachtwoordverificatie uitvoert met een mysqli verbinding. De code heeft geen foutcontrole om het leesbaar te maken:
/**
* mysqli example for a login with a stored password-hash
*/
$mysqli = new mysqli($dbHost, $dbUser, $dbPassword, $dbName);
$mysqli->set_charset('utf8');
// Find the stored password hash in the db, searching by username
$sql = 'SELECT password FROM users WHERE username = ?';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('s', $_POST['username']); // it is safe to pass the user input unescaped
$stmt->execute();
// If this user exists, fetch the password-hash and check it
$isPasswordCorrect = false;
$stmt->bind_result($hashFromDb);
if ($stmt->fetch() === true)
{
// Check whether the entered password matches the stored hash.
// The salt and the cost factor will be extracted from $hashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $hashFromDb);
}
Merk op dat het voorbeeld voorbereide instructies gebruikt om SQL-injectie te voorkomen, escapen is niet nodig in dit geval. Een equivalent voorbeeld om te lezen van een pdo verbinding kan er als volgt uitzien:
/**
* pdo example for a login with a stored password-hash
*/
$dsn = "mysql:host=$dbHost;dbname=$dbName;charset=utf8";
$pdo = new PDO($dsn, $dbUser, $dbPassword);
// Find the stored password hash in the db, searching by username
$sql = 'SELECT password FROM users WHERE username = ?';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(1, $_POST['username'], PDO::PARAM_STR); // it is safe to pass the user input unescaped
$stmt->execute();
// If this user exists, fetch the password hash and check it
$isPasswordCorrect = false;
if (($row = $stmt->fetch(PDO::FETCH_ASSOC)) !== false)
{
$hashFromDb = $row['password'];
// Check whether the entered password matches the stored hash.
// The salt and the cost factor will be extracted from $hashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $hashFromDb);
}