我正在建立一个登录系统,但似乎任何有密码的用户都可以进入我的系统。
我可以使用mysqli制作这个系统,但是我遇到了PDO的问题。我该如何解决呢。
if(isset($_POST["login-submit"])){
require "dbh.inc.php";
$username = $_POST["username"];
$user_password = $_POST["password"];
$user_password = password_hash($user_password, PASSWORD_DEFAULT);
$sql = "SELECT count(id) FROM users WHERE username = :username AND user_password = :user_password";
$stmt = $conn->prepare($sql);
$stmt->execute(["username" => $username, "user_password" => $user_password]);
if($stmt->rowCount() == 1){
session_start();
$_SESSION["username"] = $username;
header("location:../index.php?login=success");
exit();
} else {
header("location:../index.php?login=failed");
exit();
}
}
我已经测试了代码的所有其他部分,看起来它们在注册新用户时效果很好,但是如果我使用登录表单,那么任何有密码的人都可以进入我的系统。即使我输入了错误的wron密码用户,它也始终显示登录成功。我还看到了关于堆栈溢出的其他问题,但这些代码有点复杂。
您再次哈希密码以检查密码的有效性,而应使用password_verify
检查密码是否合法。
if(isset($_POST["login-submit"])){
require "dbh.inc.php";
$username = $_POST["username"];
$user_password = $_POST["password"];
$sql = "SELECT * FROM users WHERE username = :username";
$stmt = $conn->prepare($sql);
$stmt->execute(["username" => $username]);
$user = $stmt->fetch();
$hash = $user['user_password'];
if(password_verify($user_password,$hash)){
session_start();
$_SESSION["username"] = $username;
header("location:../index.php?login=success");
exit();
} else {
header("location:../index.php?login=failed");
exit();
}
}
假设您使用password_hash
函数在数据库中保存了用户密码。此外,在使用用户名获取后,获取哈希值,然后使用password_verify()
函数验证它,
(确定您的数据库是从SELECT返回row_count的数据库之一)
聚合sql将始终返回(至少)一行,因为COUNT
可能为0.假设id是唯一的主键,则不需要COUNT
。
rowCount()
不适用于SELECT语句:
PDOStatement :: rowCount()返回由相应PDOStatement对象执行的最后一个DELETE,INSERT或UPDATE语句影响的行数。
如果关联的PDOStatement执行的最后一个SQL语句是SELECT语句,则某些数据库可能会返回该语句返回的行数。但是,并不保证所有数据库都有这种行为,不应依赖于便携式应用程序。
您需要检索并检查查询执行的实际结果,而不仅仅是检查执行它时发生的事实。