Errno(0) при попытке войти с помощью оператора OO
Я пытаюсь сделать систему входа в систему более безопасной. Моя регистрация работает нормально, так что это не проблема подключения. Просто нужна свежая пара глаз, чтобы увидеть, есть ли какие-то ошибки, которые я могу пропустить, кто-нибудь может помочь, пожалуйста? Спасибо!
login.php
session_start();
if (isset($_POST['submit']))
{
$user = $_POST['username'];
$pass = $_POST['password'];
if(!($stmt = $mysqli->prepare("SELECT username, password FROM users WHERE username = ?"))){
echo "Prepare failed: (" . $mysqli->errno . ")" . $mysqli->error;
}
if(!$stmt->bind_param('s', $user)){
echo "Bind failed: (" . $stmt->errno . ")" . $stmt->error;
}
if(!$stmt->execute()){
echo "Execute failed: (" . $stmt->errno .")" . $stmt->error;
}
$userdata = $stmt->get_result();
$row = $userdata->fetch_array(MYSQLI_ASSOC);
$stmt->bind_result($user, $pass);
$stmt->store_result();
if(password_verify($pass, $row['password'])){
$_SESSION['login_user'] = $_POST['username'];
header('Location: profile.php');
exit();
}
}
else{
echo "Login Failed: (" . $stmt->errno .")" . $stmt->error;
}
$stmt->close();
$mysqli->close();
index.php (Форма входа)
<div id="loginform">
Log in details<br /><br />
<form method="post" action="login.php">
Username:
<input type="text" name="username" />
<br /><br>
Password:
<input type="password" name="password" />
<br /><br>
<input type="submit" name="submit" value="Submit" />
</form>
</div>
1 ответ
Вы не должны использовать $stmt->errno
а также $stmt->error
в Login Failed
сообщение об ошибке. Эта строка находится в else
пункт для if (isset($_POST['submit']))
, так что это не имеет ничего общего с ошибкой MySQL. Я не уверен, почему вы когда-либо получаете это сообщение, так как это должно произойти, только если вы идете в login.php
без отправки формы авторизации на index.php
,
Так как вы используете $userdata->fetch_array()
чтобы получить строку результатов из базы данных, вы также не должны использовать $stmt->bind_result()
- делать одно или другое. Я не думаю bind_result()
делает что-нибудь, так как вы никогда не звоните $stmt->fetch()
чтобы получить строку в этих переменных.
Если вы решили пойти с bind_result()
, вам нужно использовать другую переменную для пароля, потому что $pass
содержит пароль, отправленный из формы.
Вам нужно проверить, была ли строка возвращена запросом - если пользователь введет неверное имя пользователя, он не будет. Поэтому проверка пароля должна быть:
if ($row && password_verify($pass, $row['password']) {
...
}
Вы должны иметь else
пункт для этого, который сообщает, что имя пользователя или пароль были неверны. Вы не должны различать, было ли неправильное имя пользователя или пароль, это было бы плохо для безопасности (это помогает брут-форсеру знать, что он угадал имя пользователя правильно, и ему просто нужно попробовать разные пароли).
$stmt->close()
должен быть внутри if
блок.