首先,我已尽力为此找到明确的答案。其次,我的代码似乎有效,但我想确认我是以有效的方式做到这一点,而不是让自己对安全漏洞持开放态度。
首先,我在将用户添加到admin表时使用PHP password_hash;
$stmt = $dbh->prepare("INSERT INTO admin (username, password) VALUES (:username, :password)");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$password = password_hash('password', PASSWORD_DEFAULT);
其次,当用户尝试登录时,我只通过匹配用户名从admin表中检索用户,因为我在查询期间看不到检查哈希的方法(这是我不确定的部分是否存在是一种更好的方法),还可以从POST输入中定义$ password变量;
$stmt = $dbh->prepare("SELECT * FROM admin WHERE username = :username");
$stmt->bindParam(':username', $username);
$username = $_POST['username'];
// define $password for use in password verify
$password = $_POST['password'];
第三,如果查询有结果,我在用户输入上运行password_verify以检查匹配,然后根据true或false分支。
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if (password_verify($password, $row['password'])) {
session_start();
foreach ($row as $user) {
$_SESSION['user'] = $row['id'];
}
} else {
$errors = true;
}
header('location: leads.php');
}
else {
$errors = true;
}
我知道有许多不同的方法来散列/保护密码,但使用原生的password_hash函数是我决定采用的方式,我的问题是我做得对吗/有更好的方法吗?
提前致谢。
答案 0 :(得分:0)
基本上,除了已经提到的内容之外,你的代码看起来还不错。当你要求改进,特别是与性能相关的改进时,我们在这里:
username
如果您的表获得了大量条目,请从username
中删除索引,添加一个名为hash
的新列,并添加索引并重写您的插入并选择如下:
INSERT INTO admin (username, password, hash) VALUES (:username, :password, crc32(username))
SELECT * FROM admin WHERE username = :username AND hash=crc32(:username)
我假设您使用MySQL,因此在查询中添加LIMIT 1
有助于优化器并在找到行后停止搜索。
如果你只使用一行,也可以避免foreach
- 循环。
BTW:header('location: leads.php');
应该读取header('Location: leads.php');
并使用绝对路径使事情更加健壮。