问题
This is my first trial for implementing a member site with salted passwords which are all stored in the DB (MySQL). Everything works except for the error in the \'login for members\' page.
The Error:
Member login page accepts any entry to the membership site and for some reason passes my check for $result === false
This is the code for checking if member exists, please let me know what the problem is:
$servername = \'localhost\';
$username = \'root\';
$pwd = \'\';
$dbname = \'lp001\';
$connect = new mysqli($servername,$username,$pwd,$dbname);
if ($connect->connect_error){
die(\'connection failed, reason: \'.$connect->connect_error);
}
$name = mysqli_real_escape_string($connect, $_POST[\'name\']);
$password = mysqli_real_escape_string($connect, $_POST[\'password\']);
$saltQuery = \"SELECT salt FROM users WHERE name = \'$name\';\";
$result = mysqli_query($connect, $saltQuery);
if ($result === false){
die(mysqli_error());
}
$row = mysqli_fetch_assoc($result);
$salt = $row[\'salt\'];
$saltedPW = $password.$salt;
$hashedPW = hash(\'sha256\', $saltedPW);
$sqlQuery = \"SELECT * FROM users WHERE name = \'$name\' AND password = \'$hashedPW\'\";
if (mysqli_query($connect, $sqlQuery)){
echo \'<h1>Welcome to the member site \'.$name.\'</h1>\';
}else{
echo \'error adding the query: \'.$sql_q.\'<br> Reason: \'.mysqli_error($connect);
}
回答1:
Often developers struggle with the verification of a login password, because they are not sure how to handle the stored password hash. They know that the password should be hashed with an appropriate function like password_hash(), and store them in a varchar(255)
field:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
In the login form, we cannot verify the password directly with SQL, nor can we search for it, because the stored hashes are salted. Instead we...
- have to read the password-hash from the database, searching by the user id
- and afterwards can check the login password against the found hash with the password_verify() function.
Below you can find some example code, showing how to do password verification with an mysqli connection. The code has no error checking to make it readable:
/**
* 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);
}
Note that the example uses prepared statements to avoid SQL-injection, escaping is not necessary in this case. An equivalent example to read from a pdo connection could look like this:
/**
* 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);
}
来源:https://stackoverflow.com/questions/38300242/how-to-retract-a-salted-password-from-the-database-and-auth-user