【问题标题】:PHP - password_hash() verificationPHP - password_hash() 验证
【发布时间】:2019-04-25 08:06:48
【问题描述】:

以下代码应该简单明了,在注册时插入数据库会创建一个哈希,但后来当我尝试使用相同的密码登录时,它创建的哈希与数据库(我在整个过程中都有 print_r 来验证)。有人能看出我是不是忽略了一些愚蠢的事情吗?

session_start();
require_once("login.php");
$error = "";
$email = "";
$password = "";

if (isset($_GET['logout'])) {
    unset($_SESSION['id']);
    setcookie('id', '', time() - 60*60);
    $_COOKIE['id'] = "";
} else {
    if (isset($_SESSION['id']) or isset($_COOKIE['id'])) {
        header("Location: loggedinpage.php");
    }
}

if (isset($_POST["submit"])) {
    $link = mysqli_connect($hn, $un,$pw,$db);
    if($link->connect_error) die("Fatal Errror.");
    if (!$_POST["email"]) {
        $error .="An email address is required<br>";
    }
    if (!$_POST["password"]) {
        $error .="A password address is required<br>";
    }
    if ($error != "") {
        $error= "<p>There were error(s) in your form:</p>".$error;
    } else {
        if ($_POST['signup'] == 1) {
            $email = mysqli_real_escape_string($link, $_POST['email']);
            $password = mysqli_real_escape_string($link,$_POST['password']);
            $query = "SELECT id FROM `users` WHERE email = '".$email."' LIMIT 1";
            $result=$link->query($query);
            if (mysqli_num_rows($result) > 0) {
                $error = "That email address is taken.";
            } else {
                $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
                $query = "INSERT INTO `users`(`email`,`password`) VALUES ('".$email."', '".$hashedPassword."')";

                if (!mysqli_query($link,$query)) {
                    $error = "<p>Could not sign you up, please try again later</p>";
                } else {
                    $_SESSION['id'] = mysqli_insert_id($link);
                    if(isset($_POST['stayLoggedIn']) and $_POST['stayLoggedIn'] == 1) {
                        setcookie('id', mysqli_insert_id($link), time()+60*60*24);
                    }
                    header("Location: loggedinpage.php");
                }
            }
        } else {
            $email = mysqli_real_escape_string($link, $_POST['email']);
            $password = mysqli_real_escape_string($link, $_POST['password']);
            $hashedPassword = password_hash($password,PASSWORD_DEFAULT);
            $query = "SELECT * FROM users WHERE email = '".$email."' LIMIT 1";
            $result = $link->query($query);
            if ($result->num_rows > 0) {
                $row = $result->fetch_array(MYSQLI_ASSOC);
                if ($email == $row['email'] and password_verify($password,$row['password'])) {
                    if (isset($_POST['stayLoggedIn']) and $_POST['stayLoggedIn'] == 1) {
                        setcookie('id', $row['id'], time()+60*60*24);
                        header("Location: loggedinpage.php");
                    }  
                } else {
                    $error = "Incorrect Username/Password combination";
                }
            }
        }
    }
}

【问题讨论】:

  • 这似乎是一个调试问题。你可以看看这个article
  • 最好使用准备好的语句而不是手动连接字符串。或者只是使用适当的 PHP 身份验证库,而不是在用户注册/身份验证上重新发明轮子。但就像其他人说的那样,为了帮助自己,请展示您尝试过的内容以及调试时遇到的问题。
  • 您正在散列转义密码而不是输入的密码。但是当您在验证时也这样做时,这应该取消。您也不需要$email==$row['email'],因为您已经在数据库查询中搜索了此电子邮件,尽管数据库搜索不区分大小写,并且此比较区分大小写。登录时是否输入了相同大小写的E-Mail?
  • 请确认您存储哈希的数据库列的类型和大小。

标签: php verification password-hash


【解决方案1】:

试试

  if(password_verify($password, (string)$row->password)){
             //Your Code
            }

因为 password_verify 函数只返回布尔值 truefalse

还有

$hashedPassword = password_hash($password,PASSWORD_DEFAULT);

插入到Sql时只添加一次(新用户)

【讨论】:

    【解决方案2】:

    虽然它隐藏在段落的末尾,PHP documentation 确实说“建议将结果存储在可以扩展超过 60 个字符(255 个字符是一个不错的选择)的数据库列中。”

    当前的默认算法 bcrypt 生成 60 个字符长的散列。如果您的数据库列不能容纳至少这么多字符,您的哈希值将被截断并且验证将失败。


    你还有其他一些问题:

    • 您在生成哈希之前修改密码(使用mysqli_real_escape_string()
    • 你没有使用prepared statements
    • 您似乎依赖 cookie 进行身份验证。 Cookie 是用户生成的数据,不可信任!这就是 PHP 提供会话支持的原因,因为数据存储在服务器上。
    • 您不应使用查询来检查现有电子邮件地址,而应在数据库中的电子邮件列上设置唯一索引。

    【讨论】:

      猜你喜欢
      • 2014-01-15
      • 1970-01-01
      • 2022-01-09
      • 2015-05-09
      • 2021-07-26
      • 2015-06-03
      相关资源
      最近更新 更多