Это моя первая пробная версия для реализации сайта участника с солеными паролями, которые все хранятся в БД (MySQL). Все работает, за исключением ошибки на странице «Вход для пользователей».
Ошибка:
Страница входа пользователя принимает любая запись на сайт членства и по какой-то причине проходит мой чек на $result === false
Это код для проверки, если член существует, пожалуйста, дайте мне знать, в чем проблема:
$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);
}
Часто разработчики борются с проверкой пароля для входа в систему, потому что они не уверены, как обращаться с хешем сохраненного пароля. Они знают, что пароль должен быть хеширован с помощью соответствующей функции, такой как password_hash (), и хранить их в varchar(255)
поле:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
В форме входа в систему мы не можем проверить пароль напрямую с помощью SQL, а также не можем его найти, потому что сохраненные хэши засолены. Вместо этого мы …
Ниже вы можете найти пример кода, показывающий, как выполнить проверку пароля с помощью MySQLi подключение. В коде нет проверки ошибок, чтобы сделать его читабельным:
/**
* 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);
}
Обратите внимание, что в примере используются подготовленные операторы, чтобы избежать SQL-инъекций, убегать не нужно в этом случае. Эквивалентный пример для чтения из п.д.о. соединение может выглядеть так:
/**
* 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);
}
Других решений пока нет …