Mysql
 sql >> Database >  >> RDS >> Mysql

Come ritirare una password salata dal database e dall'utente di autenticazione?

Spesso gli sviluppatori hanno difficoltà con la verifica di una password di accesso, perché non sono sicuri di come gestire l'hash della password memorizzata. Sanno che la password dovrebbe essere sottoposta a hash con una funzione appropriata come password_hash( ) e salvarli in 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);

Nel modulo di accesso, non possiamo verificare la password direttamente con SQL, né cercarla, perché gli hash memorizzati sono salati. Invece noi...

  1. devono leggere l'hash della password dal database, cercando per ID utente
  2. e successivamente è possibile confrontare la password di accesso con l'hash trovato con verifica_password() funzione.

Di seguito puoi trovare un codice di esempio, che mostra come eseguire la verifica della password con un mysqli connessione. Il codice non ha errori di controllo per renderlo leggibile:

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

Si noti che l'esempio utilizza istruzioni preparate per evitare l'iniezione SQL, non è necessario eseguire l'escape in questo caso. Un esempio equivalente da leggere da un pdo la connessione potrebbe essere simile a questa:

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