Как проверить, введет ли пользователь правильный пароль для входа?
Вот что (из множества комбинаций …) Я делаю:
<? $login = $_POST['login']; $password = $_POST['password']; mysql_connect('localhost', 'root', 'abc123'); mysql_select_db('aun_vox') or die(mysql_error()); $q = mysql_query("SELECT password FROM customer WHERE login='$login'"); $db_pass = mysql_result($q, 0); if(md5($password) == $db_pass) { echo "You did it."; } else echo "Wrong."; ?>
Как я могу видеть из вывода, что-то не так в бит mysql_result
, но я не могу понять правильный путь.
Может кому-то помочь.
Я вижу, что вы храните хэш пароля в базе данных, но в интересах других читателей никогда не храните пароли в текстовом виде в базе данных. Вы не хотите быть похожим на Monster.com.uk !
Вы должны использовать более сильную функцию хеширования, чем MD5()
. В идеале вы должны использовать SHA256. Этот хэш-метод доступен на PHP с использованием функции hash()
.
Вы также должны применить случайную соль к паролю. Храните другое значение соли для учетной записи каждого пользователя. Это помогает атаковать словарные атаки и атаки радужных таблиц .
Вы должны научиться использовать расширение mysqli вместо старого расширения mysql. Mysqli поддерживает параметризованные запросы, поэтому вы можете уменьшить уязвимость для некоторых атак SQL-инъекций.
Вот пример кода. Я не тестировал его, но он должен быть очень близок к работе:
$input_login = $_POST['login']; $input_password = $_POST['password']; $stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?"); $stmt->bind_param("s", $input_login); $stmt->execute(); $stmt->bind_result($password_hash, $salt); while ($stmt->fetch()) { $input_password_hash = hash('sha256', $input_password . $salt); if ($input_password_hash == $password_hash) { return true; } // You may want to log failed password attempts here, // for security auditing or to lock an account with // too many attempts within a short time. } $stmt->close(); // No rows matched $input_login, or else password did not match return false;
Некоторые другие люди предполагают, что запрос должен протестировать для login = ? AND password = ?
login = ? AND password = ?
но я не люблю это делать. Если вы это сделаете, вы не можете знать, не удалось ли выполнить поиск, потому что логин не существует или из-за того, что пользователь указал неверный пароль.
Конечно, вы не должны показывать пользователю, который вызвал неудачную попытку входа в систему, но вам может понадобиться знать, поэтому вы можете регистрировать подозрительную активность.
@Javier говорит в своем ответе, что вы не должны извлекать пароль (или хэш пароля в этом случае) из базы данных. Я не согласен.
Хавьер показывает вызов md5()
в PHP-коде и отправляет полученную хэш-строку в базу данных. Но это не помогает легко солить пароль. Вы должны сделать отдельный запрос, чтобы получить соль этого пользователя, прежде чем вы сможете сделать хэш в PHP.
Альтернативой является отправка пароля открытого текста по сети из вашего приложения PHP на ваш сервер базы данных. Любой, кто перехватывает вашу сеть, может видеть этот пароль. Если вы регистрируете SQL-запросы, любой, кто получает доступ к журналам, может видеть пароль. Мотивированные хакеры могут даже погрузиться в хранилище, чтобы найти старый резервный носитель для файловой системы, и могут читать файлы журнала таким образом!
Меньший риск состоит в том, чтобы получить хэш-строку пароля из базы данных в приложение PHP, сравнить ее с хешем ввода пользователя (также в PHP-коде), а затем отбросить эти переменные.
Во-первых, убедитесь, что вы правильно удалили переменные перед их использованием в запросе – используйте mysql_real_escape_string ().
Тогда почему бы не использовать функцию MySQL MD5 для проверки правильности входа в ваш запрос?
SELECT login FROM customer WHERE login='$login' AND password = MD5('$password')
Затем просто используйте mysql_num_rows (), чтобы подсчитать количество возвращаемых строк.
некоторые моменты:
то, что я обычно делаю, это что-то вроде:
$q = preparestatement ("SELECT id FROM customer WHERE login=? AND password=?"); bindvalue ($q, $_POST['login']); bindvalue ($q, md5($_POST['password'])); $id = execprepared ($q); if($id) { echo "You did it."; } else { echo "Wrong."; }
Получить пароль от пользователя из метода FORM POST и конвертировать $ _POST ['password'] // из формы // в соответствующий формат в php / jsp / любой другой, а затем сравнить с отформатированным паролем в вашей базе данных
Обычно используется md5-шифрование, когда вы можете сравнить md45 ('{$ _ POST [' password ']}') = присутствует в вашем db; или вообще mysql использовать пароль («ваш пароль») при создании пароля, поэтому сначала запустите свой $ _POST ['password'] в mysqli_query и mysqli_fetch_array, чтобы получить зашифрованное значение пароля, а затем сравните.
Больше, чем PHP 5.6, вы можете использовать функцию hash_compare.
$users_password = hash(sha256,$salt.$post_password); if (hash_equals($users_dbpassword, $users_password)) { //pass is good } else { // pass failed }