-1

首先,我已尽力为此找到明确的答案。其次,我的代码似乎可以工作,但我想确认我正在以一种有效的方式执行此操作,并且不会让自己面临安全漏洞。

首先,我在将用户添加到管理表时使用 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);

其次,当用户尝试登录时,我只通过匹配用户名从管理表中检索用户,因为我看不到在查询期间检查哈希的方法(这是我不确定是否有更好的部分方式),并从 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 以检查匹配,然后根据真或假进行分支。

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 函数是我决定采用的方式,我的问题是我做得对吗/有更好的方法吗?

提前致谢。

4

1 回答 1

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如果您只使用一行,也可以避免 -loop 。

顺便说一句:header('location: leads.php');应该阅读header('Location: leads.php');和使用绝对路径会使事情变得更加健壮。

于 2015-06-04T13:20:58.503 回答