登录页面有准备好的语句的问题

问题描述 投票:0回答:1

我正在尝试为我的网站创建一个登录页面。我从另一个我建立的站点复制并粘贴了该站点,该站点可以正常运行。我使用echo语句进行了测试,但是尝试登录时得到的只是登录页面的简化版本。它会在将此代码粘贴到HTML代码中的位置处截断。我已经看过它很多次了,双眼交叉,所以我不确定自己缺少什么!非常感谢您的帮助!

<?php
                    if($_SERVER['REQUEST_METHOD'] != 'POST') {
                        echo '<form method="post" action=""><p><label for="username">Username:</label><input type="text" name="username" id="username" title="username"></p><p><label for="password">Password:</label><input type="password" name="password" id="password" title="password"></p><p><input type="submit" name="login" id="login" value="Login"></p></form>';
                    } else {
                        $username = $_POST['username'];
                        $password = $_POST['password'];

                        if($username == "") {
                            echo '<p>Please enter your username</p>';
                        } else {
                            if($password == "") {
                                echo '<p>Please enter your password</p>';
                            } else {
                                $mysqli = new mysqli("localhost","USER","PASSWORD","DB");
                                if($mysqli->connect_error) {
                                    exit('Error connecting to database');
                                } else {
                                    $stmt = $mysqli->prepare("SELECT admin_id, admin_username, admin_password FROM admin WHERE admin_username = ?");
                                    $stmt->bind_param("s", $username);
                                    $stmt->execute();
                                    $stmt->bind_result($id, $user, $pass);
                                    while($stmt->fetch()) {
                                       if(password_verify($password, $pass)) {
                                           echo '<p>Logged in</p>';
                                       } else {
                                           echo '<p>Incorrect Password</p>';
                                       }//verify password
                                    } // statements
                                    $stmt->close();
                                } // connection test
                            } // check password
                        } // check username
                    }
                    ?>
mysql authentication prepared-statement
1个回答
0
投票

我测试了您的代码,它可以正常工作。没有什么问题。

我建议尽管您说过您仔细检查了数据库,但问题是此PHP代码连接到的数据库中不存在用户名。也许您检查了错误的数据库。

我按原样测试了您的代码,然后对其进行了一些重构。我以为我会告诉你我写这个的方式:

这显示error_log()的使用,该输出到http错误文件。将技术错误消息输出到可以阅读的地方是一个好习惯,但在浏览器输出中会出现一个更加用户友好的错误。您不想混淆您的用户。

$mysqli = new mysqli("...", "...", "...", "...");
if ($mysqli->connect_error) { 
    error_log($mysqli->connect_error);
    die('Error connecting to database, contact site administrator');
}   

将SQL放入变量中,因此,如果有问题,可以将其输出到错误日志中。同样,用户不需要知道技术细节,只需知道它失败了,而网站管理员需要修复它。

$sql = "
  SELECT admin_id, admin_username, admin_password 
  FROM admin 
  WHERE admin_username = ?";
if (($stmt = $mysqli->prepare($sql)) === false) {
  error_log($mysqli->error);
  error_log("SQL = [$sql]");
  die("Database error, contact site administrator");
}   

每个mysqli函数在任何步骤都出现问题时都返回false。您需要检查一下。

if ($stmt->bind_param("s", $username) === false) {
  error_log($stmt->error);
  die("Database error, contact site administrator");
} 
if ($stmt->execute() === false) {
  error_log($stmt->error);
  die("Database error, contact site administrator");
} 
if ($stmt->store_result() === false) {
  error_log($stmt->error);
  die("Database error, contact site administrator");
}

如果行数为零,则表示用户名不匹配。您想在错误日志中了解此信息,但不要向用户透露。他们应该只知道用户名或密码错误,而不是哪个错误。

if ($stmt->num_rows == 0) {
  error_log("Username '$username' not found");
  die("Incorrect username or password");
} 
if ($stmt->bind_result($id, $user, $pass) === false) {
  error_log($stmt->error);
  die("Database error, contact site administrator");
} 

应该只有与用户名匹配的一行。因此,如果没有匹配的密码,请随时使用die()。

while ($stmt->fetch()) {
   if (password_verify($password, $pass) === false) {
       error_log("Username '$username' found, but password is wrong");
       die("Incorrect username or password");
   }
} 
$stmt->close();

最后,最后一步:如果我们走到了这一步,那一定是成功的。如果您在每个错误情况下都早于die(),那么您就不必担心深度嵌套的代码块。

echo "<p>Welcome! You are logged in, $username</p>";
© www.soinside.com 2019 - 2024. All rights reserved.