Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment retirer un mot de passe salé de la base de données et de l'utilisateur auth ?

Souvent, les développeurs ont du mal à vérifier un mot de passe de connexion, car ils ne savent pas comment gérer le hachage du mot de passe stocké. Ils savent que le mot de passe doit être haché avec une fonction appropriée comme password_hash( ) , et stockez-les dans un varchar(255) champ :

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);

Dans le formulaire de connexion, nous ne pouvons pas vérifier le mot de passe directement avec SQL, ni le rechercher, car les hachages stockés sont salés. Au lieu de cela, nous...

  1. doivent lire le hachage du mot de passe à partir de la base de données, en recherchant par l'identifiant de l'utilisateur
  2. et ensuite peut vérifier le mot de passe de connexion par rapport au hachage trouvé avec le password_verify() fonction.

Ci-dessous vous pouvez trouver un exemple de code, montrant comment faire la vérification du mot de passe avec un mysqli lien. Le code n'a pas de vérification d'erreur pour le rendre lisible :

/**
 * 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);
}

Notez que l'exemple utilise des instructions préparées pour éviter l'injection SQL, l'échappement n'est pas nécessaire dans ce cas. Un exemple équivalent à lire à partir d'un pdo la connexion pourrait ressembler à ceci :

/**
 * 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);
}