Эффективная проверка хешированного пароля из базы данных

во-первых, я старался изо всех сил, чтобы найти окончательный ответ на этот вопрос. Во-вторых, мой код работает, но я хочу подтвердить, что я делаю это эффективно и не оставляю себя открытым для нарушений безопасности.

Во-первых, я использую PHP password_hash при добавлении пользователя в таблицу администратора;

$stmt = $dbh->prepare("INSERT INTO admin (username, password) VALUES (:username, :password)");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);

$password = password_hash('password', PASSWORD_DEFAULT);

Во-вторых, когда пользователь пытается войти в систему, я извлекаю пользователей из таблицы admin, сопоставляя ТОЛЬКО имя пользователя, так как я не мог найти способ проверить хэш во время запроса (это часть, в которой я не уверен, если есть лучший way), а также определить переменную $ password из входных данных POST;

$stmt = $dbh->prepare("SELECT * FROM admin WHERE username = :username");
$stmt->bindParam(':username', $username);
$username = $_POST['username'];
// define $password for use in password verify
$password = $_POST['password'];

В-третьих, если в результате запроса есть результат, я запускаю password_verify на вводе пользователя, чтобы проверить совпадение, а затем выполняю ответвление в зависимости от true или false.

if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if (password_verify($password, $row['password'])) {
session_start();
foreach ($row as $user) {
$_SESSION['user'] = $row['id'];
}
} else {
$errors = true;
}
header('location: leads.php');
}
else {
$errors = true;
}

Я знаю, что есть много разных способов хешировать / защищать пароли, но я решил пойти с помощью встроенных функций password_hash, мой вопрос: правильно ли я это сделал / есть ли лучший способ?

Заранее спасибо.

-1

Решение

По сути, ваш код выглядит вполне нормально, кроме уже упомянутых вещей. Когда вы просите об улучшениях, особенно связанных с производительностью, мы начинаем:

  • Добавить индекс на username
  • Если в вашей таблице много записей, удалите индекс из usernameдобавьте новый столбец с именем hash с индексом и переписать вставку и выберите как это:

    INSERT INTO admin (username, password, hash) VALUES (:username, :password, crc32(username))

    SELECT * FROM admin WHERE username = :username AND hash=crc32(:username)

Я предполагаю, что вы используете MySQL, поэтому добавление LIMIT 1 на ваш запрос помогает оптимизатор и прекращает поиск после того, как строка найдена.

Избегать foreach-loop также возможно, если вы работаете только с одной строкой.

КСТАТИ: header('location: leads.php'); должен прочесть header('Location: leads.php'); и использование абсолютных путей делает вещи более устойчивыми.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]