php 在PDO中使用password_verify的正确方法是什么?

wi3ka0sx  于 2023-03-16  发布在  PHP
关注(0)|答案(2)|浏览(113)

在我的php PDO代码中,我似乎无法让password_verify工作。我的密码域存储为varchar(255)。我一直在阅读类似的问题,但从我可以告诉我,我已经设置好了。我一定还缺少一些东西。我的注册页面如下。

$user = $_POST['username']
$pass = $_POST['pass'];
$passH = password_hash($pass, PASSWORD_DEFAULT);
$query = $con->prepare("INSERT INTO emps (user, pass) VALUES (?, ?)");
$query->execute([$user, $passH]);

加密密码现在已成功存储在数据库中。
我的登录页面如下..

if(isset($_POST['login'])) {
  $username = $_POST['username'];
  $pass = trim($_POST['pass'];
  $passH = password_hash($pass, PASSWORD_DEFAULT);
  $sel_user = $con->prepare("SELECT id, username, pass, gid FROM emps WHERE gid!=4 AND username=?");
  $sel_user->execute([$username]);
  $check_user=$sel_user->fetch();
  if(count($check_user)>0 && password_verify($passH, $check_user['pass'])) {
    $_SESSION['username']=$check_user['username'];
    header("Location: xadmin.php");
    exit;
  }
  else {
    echo "<script>alert('Not Found')</script>";

登录页正文..

<form action="login.php" method="post">
    <table width="100%" border="0">
        <tbody>
            <tr>
                <td bgcolor="#3B3B3B" height ="35" class="BodyTxtB" align="center">Administrator Login</td></tr>
            <tr height="20"><td></td></tr>
            <tr>
              <td class="BodyTxtB" align="center">Username</td>
            </tr>
            <tr>
              <td class="BodyTxtB" align="center"><input type="text" class="BodyTxtBC" name="username" required="required"/></td>
            </tr>
            <tr height="20"><td></td></tr>
            <tr>
              <td class="BodyTxtB" align="center">Password</td>
            </tr>
            <tr>
              <td class="BodyTxtB" align="center"><input type="password" class="BodyTxtBC" name="pass" required="required"/></td>
            </tr>
            <tr height="20"><td></td></tr>
            <tr height="35"><td align="center"><input type="image" src="images/btn_login.jpg" name="login" value="Login"/>
            <input type="hidden" name="login" value="Login" /></td></tr>
            <tr height="20"><td></td></tr>
         </tbody>
     </table>
   </form>

有人能发现错误吗?

332nm8kg

332nm8kg1#

password_verify()的参数是(1)要检查的未散列密码和(2)用作引用的散列密码。在比较之前,您将对第一个参数进行散列。
相反,您应该执行password_verify($pass /** the unhashed one */, $check_user['pass'])

$stmt = $con->prepare("SELECT id, username, pass, gid FROM emps WHERE username=?");
$stmt->execute([$_POST['username']]);
$user = $stmt->fetch();
if ($user && password_verify($_POST['pass'], $check_user['pass'])) {
    $_SESSION['username']=$user['username'];
    header("Location: xadmin.php");
    exit;
}

此外,修改密码也不是个好主意,如果密码中包含空格(你应该允许它这样做)怎么办?

tv6aics1

tv6aics12#

RTM?http://php.net/password_verify

boolean password_verify ( string $password , string $hash )

你传入$passwordPLAINTEXT密码,你自己不对它进行哈希运算,这只会生成一个新的哈希值,使用不同的盐,使得比较变得毫无意义和不可能。
password_verify将从$hash中提取适当的salt,使用它来散列$password本身,然后比较散列字符串。
例如,password_verify基本上就是这样:

function password_verify($pw, $hash) {
    $salt = get_salt_from($hash);
    $temp = password_hash($pw, $salt);

    return ($temp == $hash);
}

相关问题