密码与我的PHP登录表单不匹配

时间:2016-08-10 09:04:37

标签: php pdo

我已经尝试了很多次,但每次都说Email & Password Not Matched!。我找不到任何解决方案。我使用 PDO 进行数据库连接。我认为我的会话有问题但是我找不到错误。到目前为止我已经尝试过:

<?php
/* For Login */

include 'db.php';
if (isset($_POST['login'])) {
    $email = $_POST['email'];
    $hash  = $_POST['password'];
    $password  = password_hash($hash, PASSWORD_DEFAULT);
    $records = $db->prepare("SELECT id FROM users WHERE email=? AND password=?");
    $records->execute(array($email,$password));
    $userdata = $records->fetch(PDO::FETCH_ASSOC);
    if (!empty($email) && !empty($hash)) {
        if (count($userdata)>0 ) {
            //session_start();
            $_SESSION['email'] = $userdata['email'];
            $_SESSION['password'] = $userdata['password'];
            if ($_POST['password'] == $userdata['password']) {
                echo "<div class='alert alert-success text-center'>
                      <strong>Successfully</strong> Login</div>";
                exit;
            }else{
                echo "<div class='alert alert-danger text-center'> 
                      <strong>Email & Password</strong> Not Matched!
                      </div>";
            }
        }else{
            echo "Email and Password Not Matched!";
            echo $_SESSION['email'];
        }
    }else{
        echo "<div class='alert alert-danger text-center'>
              <strong>Email & Password</strong> must not be empty!</div>";
    }
}
?>

提前致谢。

1 个答案:

答案 0 :(得分:3)

您正在重新散列传入密码,这不是password_hash()完成后如何使用password_verify()来测试数据库上的散列密码与传递的纯文本密码相同在用户。

如果您连续两次使用相同的密码运行password_hash(),则每次都会获得不同的哈希值,因此您必须使用password_verify()来验证输入的密码与数据库中的哈希值。

从CLI尝试此操作,它将演示:

$password = 'WoopsADaisy';
echo password_hash($password, PASSWORD_DEFAULT).PHP_EOL;
echo password_hash($password, PASSWORD_DEFAULT).PHP_EOL;

输出,仅当我将其作为测试运行时返回

$2y$10$t52UeqDlP897iD/n6uo71OErIFP5c4wsli6gLRNdfyQLkv8m6Wxs2
$2y$10$FczpgQIsmpzr6.vhYA6d3.QmEe3i3HR4WkapLrtO/BLK4Uul0WjUa

你不会得到相同的哈希值,但你会得到2个不同的哈希值!

这也意味着您需要稍微修改一下

<?php
/* For Login */

// always start the session at the top of a script
session_start();

include 'db.php';

// isset can test many variables at the same time
if (isset($_POST['login'], $_POST['email'], $_POST['password'])) {
    $email      = $_POST['email'];
    $plain_pwd  = $_POST['password'];

    // get hashed password to test
    // also you were never actually retrieving the email
    $records = $db->prepare("SELECT id,password,email 
                             FROM users WHERE email=?");
    $staus = $records->execute(array($email));

    // test the query actually worked
    if ( $staus === false ) {
        print_r($db->errorInfo());
        exit;
    }

    $userdata = $records->fetch(PDO::FETCH_ASSOC);



    if ( password_verify($plain_pwd, $userdata['password']) ) {
        // the entered password is GOOD

        $_SESSION['email'] = $userdata['email'];

        // never need to store in session
        //$_SESSION['password'] = $userdata['password'];

        echo "<div class='alert alert-success text-center'>
              <strong>Successfully</strong> Login</div>";
    } else {
        echo "Email and Password do not Match!";
    }

}else{
    echo "<div class='alert alert-danger text-center'>
          <strong>Email & Password</strong> must not be empty!</div>";
}
?>
  

其他可以在散列密码时绊倒你的东西。确保表上的列password足够长以容纳散列密码。 password_hash()使用PASSWORD_DEFAULT创建的60个字符,但由于默认哈希算法可能会随着时间的推移而改变,如果需要加强,建议将此列设置为varchar(255)以保证数据库的未来性。

     

参考文献:

     

password_hash()

     

password_verify()