将散列密码与php中的文件密码进行比较

时间:2018-03-14 15:01:34

标签: php

好的,所以我有一个脚本,您可以在其中注册一个帐户,并在.txt文件中添加一行代码和密码。问题是它由于某种原因没有正确检查密码。

这是.txt文件的内容:

aa;$2y$10$VPU65Et3ndqpCuxilZSLYO5Z9hA1rHy0BVCCBRANsqzGy.TKncKNG
alan;$2y$10$69osQF6KBRfYeHRdqkkzRenXpwMMR4jIK5n0xxMJRQTFsKsgR2ZN2
ala;$2y$10$/rcufuupuBVoG216aF7kfOlkvBxwHbI1kzsFg9BbQ2fbj/OyOQmeK

这是代码:

<form action="login.php" method="post">
Username: <input type="text" name="namn"><br> Password: <input 
type="text" name="pass"><br>
<input type="submit" name="login" value="Log in">
</form>
<?php
session_start();
$userN = $_POST['namn'];
$passW = password_hash($_POST['pass'], PASSWORD_DEFAULT);
$userList = file ('users.txt');

if (isset($_POST['login'])) {
    if (empty($userN) && empty($_POST['pass'])) {
        echo "Both fields are empty.";
    } else if (empty($_POST['pass'])) {
        echo "Please enter your password";
    } else if (empty($userN)) {
        echo "Please enter your username.";
    } else {
        foreach($userList as $row) { 
            $parts = explode(";",$row);
                if($userN==$parts[0] && password_verify($passW, $parts[1])) {
                    $_SESSION['username'] = $_POST['namn'];
                    header("Location:index.php");
                } else {
                    echo "Wrong username/password!";
                }
           }
      }
 }

它只是说“用户名/密码错误!用户名/密码错误!用户名/密码错误!”当我尝试登录时。希望它没有什么太明显和一个愚蠢的问题。

请告诉我是否应该包含其他任何内容。

1 个答案:

答案 0 :(得分:0)

你得到了奇怪的输出,因为你在代码中犯了两个错误。

<强> 1。您未正确使用DataFrame.to_dictpassword_hash()

要验证您是否拥有相同的密码,请从$_POST获取密码并通过$passW = password_hash($_POST['pass'], PASSWORD_DEFAULT);哈希。然后使用命令pasword_verify()检查此密码是否在您的文件中。无论如何,正确的方法是,当您保存密码时才使用password_verify($passW, $parts[1])。如果要检查密码是否已保存,请使用password_hash()和未使用密码的密码:

$passW = $_POST['pass'];
....
if ($userN==$parts[0] && password_verify($passW, $parts[1])) {
...

这样检查就可以了。

<强> 2。您可以回显循环中每次迭代的登录输出

每次登录尝试时,您都会收到文本"Wrong username/password!"三次。这是因为行echo "Wrong username/password!";位于foreach循环内,而您的文件包含三行。相反,您不应该使用条件的else块来处理错误登录尝试的输出,因为您离开页面以防止成功登录。因此,您可以在重定向后安全地添加password_verify()以停止进一步的代码执行并以任何其他方式打印出错误消息。因为检查$userN === $parts[0]也是该检查的一部分,所以无论如何都会对每一行执行检查,这导致输出错误。

foreach($userList as $row) { 
    $parts = explode(";",$row);
    if($userN === $parts[0] && password_verify($passW, $parts[1])) {
        $_SESSION['username'] = $_POST['namn'];
        header("Location:index.php");
        die();
    }
}
echo "Wrong username/password!";

由于die()命令,只有在登录失败时才会打印错误消息。因为它在foreach循环之外,所以它只打印一次。