sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo retirar una contraseña salada de la base de datos y el usuario de autenticación?

A menudo, los desarrolladores luchan con la verificación de una contraseña de inicio de sesión porque no están seguros de cómo manejar el hash de contraseña almacenado. Saben que la contraseña debe codificarse con una función apropiada como password_hash( ) y almacenarlos en un varchar(255) campo:

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

En el formulario de inicio de sesión, no podemos verificar la contraseña directamente con SQL, ni podemos buscarla, porque los hashes almacenados están salteados. En cambio nosotros...

  1. tiene que leer el hash de la contraseña de la base de datos, buscando por la identificación del usuario
  2. y luego puede verificar la contraseña de inicio de sesión con el hash encontrado con contraseña_verificar() función.

A continuación, puede encontrar un código de ejemplo que muestra cómo verificar la contraseña con un mysqli conexión. El código no tiene comprobación de errores para que sea legible:

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

Tenga en cuenta que el ejemplo usa sentencias preparadas para evitar la inyección SQL, no es necesario escapar en este caso. Un ejemplo equivalente para leer de un pdo la conexión podría verse así:

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