Следующий код должен быть прямым и простым, вставка в базу данных при регистрации создает хеш, но позже, когда я пытаюсь войти в систему с тем же паролем, хэш, который он создает, не соответствует тому, что находится в базе данных (я имел print_r для проверки). Может кто-нибудь увидеть, если я просто не замечаю чего-то тупого?
session_start();
require_once("login.php");
$error = "";
$email = "";
$password = "";
if (isset($_GET['logout'])) {
unset($_SESSION['id']);
setcookie('id', '', time() - 60*60);
$_COOKIE['id'] = "";
} else {
if (isset($_SESSION['id']) or isset($_COOKIE['id'])) {
header("Location: loggedinpage.php");
}
}
if (isset($_POST["submit"])) {
$link = mysqli_connect($hn, $un,$pw,$db);
if ($link->connect_error) die("Fatal Errror.");
if (!$_POST["email"]) {
$error . = "An email address is required<br>";
}
if (!$_POST["password"]) {
$error . = "A password address is required<br>";
}
if ($error != "") {
$error= "<p>There were error(s) in your form:</p>".$error;
} else {
if ($_POST['signup'] == 1) {
$email = mysqli_real_escape_string($link, $_POST['email']);
$password = mysqli_real_escape_string($link,$_POST['password']);
$query = "SELECT id FROM `users` WHERE email = '".$email."' LIMIT 1";
$result=$link->query($query);
if (mysqli_num_rows($result) > 0) {
$error = "That email address is taken.";
} else {
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$query = "INSERT INTO `users`(`email`,`password`) VALUES ('".$email."', '".$hashedPassword."')";
if (!mysqli_query($link,$query)) {
$error = "<p>Could not sign you up, please try again later</p>";
} else {
$_SESSION['id'] = mysqli_insert_id($link);
if (isset($_POST['stayLoggedIn']) and $_POST['stayLoggedIn'] == 1) {
setcookie('id', mysqli_insert_id($link), time()+60*60*24);
}
header("Location: loggedinpage.php");
}
}
} else {
$email = mysqli_real_escape_string($link, $_POST['email']);
$password = mysqli_real_escape_string($link, $_POST['password']);
$hashedPassword = password_hash($password,PASSWORD_DEFAULT);
$query = "SELECT * FROM users WHERE email = '".$email."' LIMIT 1";
$result = $link->query($query);
if ($result->num_rows > 0) {
$row = $result->fetch_array(MYSQLI_ASSOC);
if ($email == $row['email'] and password_verify($password,$row['password'])) {
if (isset($_POST['stayLoggedIn']) and $_POST['stayLoggedIn'] == 1) {
setcookie('id', $row['id'], time()+60*60*24);
header("Location: loggedinpage.php");
}
} else {
$error = "Incorrect Username/Password combination";
}
}
}
}
}
Было бы лучше использовать подготовленные операторы вместо ручного объединения строк. Или просто используйте подходящую библиотеку аутентификации PHP и не изобретайте велосипед при регистрации / аутентификации пользователя. Но, как говорили другие, чтобы помочь себе, покажите, что вы пробовали и где застряли во время отладки.
Вы хешируете экранированный пароль вместо введенного. Но поскольку вы делаете это также при проверке, это должно прекратиться. Вам также не нужен $email==$row['email'], поскольку вы уже ищете это электронное письмо в запросе к базе данных, хотя поиск в БД будет нечувствительным к регистру, и это сравнение чувствительно к регистру. Вы вводили E-Mail с таким же регистром при входе в систему?
Подтвердите тип и размер столбца базы данных, в котором вы храните хэши.
@ miken32 извините, пришлось отправиться прямо на День благодарения, прежде чем опубликовать его. Спасибо, хотя я считаю, что теперь это была проблема с размером столбца хешируемого пароля. Собираюсь попытаться исправить это
Вы можете подтвердить размер и тип?
электронная почта - varchar (50), и я изменил пароль на varchar (255), ранее он тоже был на 50, но по-прежнему возникает та же проблема.
Теперь он работает, но только тогда, когда у меня установлен флажок оставаться в системе. Обратите внимание, что я удалил перенаправление заголовка на уровень ниже. Я понимаю, что когда я опубликовал, это было связано с тем, что нужно было войти в систему, но после перемещения оттуда он не будет перенаправлять, если я не поставлю этот флажок.






пытаться
if (password_verify($password, (string)$row->password)){
//Your Code
}
из-за функции password_verify возврат только Boolean true или false
И
$hashedPassword = password_hash($password,PASSWORD_DEFAULT);
Добавляйте только один раз, когда вы вставляете в Sql (новый пользователь)
Хотя он спрятан в конце абзаца, Документация PHP действительно говорит, что «рекомендуется сохранить результат в столбце базы данных, размер которого может превышать 60 символов (255 символов было бы хорошим выбором)».
Текущий алгоритм по умолчанию, bcrypt, генерирует хэши длиной 60 символов. Если столбец вашей базы данных не может содержать хотя бы такое количество символов, ваши хэши будут усечены, и проверка не удастся.
У вас есть еще несколько проблем:
mysqli_real_escape_string())
Похоже, это проблема отладки. Вы можете взглянуть на этот статья.