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 блок.

Другие вопросы по тегам