无法登录。密码提交不匹配存储在DB中的密码。 - PHP,Password_hash

时间:2016-09-15 21:04:56

标签: php password-hash

我已将password_hash PHP函数添加到我的注册页面,用户在其中创建帐户并存储密码。我在注册表单中应用了相同的password_hash代码行。数据保存在数据库中,但是当我尝试登录时,提交的密码与存储的密码不匹配。我也尝试了password_verify函数,我在PHP手册中读到过,但没有任何作用。在尝试和尝试之后,我真的不知道还能做什么,所以如果有人有建议,我会很感激。

P.S。我目前正在使用PHP 5.6.25版。

以下是代码:

<?php
// AJAX CALLS THIS LOGIN CODE TO EXECUTE
if(isset($_POST["e"])){
    // CONNECT TO THE DATABASE
    include_once("PHP_Includes/db.php");
    // GATHER THE POSTED DATA INTO LOCAL VARIABLES AND SANITIZE
    $e = mysqli_real_escape_string($db, $_POST['e']);
    $p = password_hash($_POST['p'], PASSWORD_DEFAULT,['cost' => 15]);
    // FORM DATA ERROR HANDLING
    if($e == "" || $p == ""){
        echo "login_failed";
        exit();
    } else {
    // END FORM DATA ERROR HANDLING
        $sql = "SELECT id, username, password FROM users WHERE email='$e' AND activated='1' LIMIT 1";
        $query = mysqli_query($db, $sql);
        $row = mysqli_fetch_row($query);
        $db_id = $row[0];
        $db_username = $row[1];
        $db_pass_str = $row[2];
        if($p != $db_pass_str){
            echo "login_failed";
            exit();
        } else {
            // CREATE THEIR SESSIONS 
            $_SESSION['userid'] = $db_id;
            $_SESSION['username'] = $db_username;
            $_SESSION['password'] = $db_pass_str;
        }
    }
    exit();
}
?>

login()函数:

function login(){
    var e = _("email").value;
    var p = _("password").value;
    if(e == "" || p == ""){
        _("status").innerHTML = "Fill out all of the form data";
    } else {
        _("loginbtn").style.display = "none";
        _("status").innerHTML = 'please wait ...';
        var ajax = ajaxObj("POST", "index.php");
        ajax.onreadystatechange = function() {
            if(ajaxReturn(ajax) == true) {
                if(ajax.responseText == "login_failed"){
                    _("status").innerHTML = "Login unsuccessful, please try again.";
                    _("loginbtn").style.display = "block";
                } else {
                    window.location = "user.php?u="+ajax.responseText;
                }
            }
        }
        ajax.send("e="+e+"&p="+p);
    }
}

1 个答案:

答案 0 :(得分:3)

您对password_hash()如何运作的理解有点过时了。与使用sha1()md5()(两者都应避免存储密码!)不同,password_hash()每次调用都不会返回相同的字符串,即使是相同的字符串。

例如:

var_dump(password_hash("hello_world", PASSWORD_DEFAULT));
var_dump(password_hash("hello_world", PASSWORD_DEFAULT));
输出

(例如,password_hash()返回的字符串每次调用时都会有所不同)

string(60) "$2y$10$Da2HG0dcvfI.3qBivR8Mpu9U5S06PBZ3415lDEh3EcDZ/fELZzHgC"
string(60) "$2y$10$zL6745UkPEvZWS5w1Keco.IKi7ssl.PqldGxucDYHaJW3vgCc366a"

请注意,即使在相同的值上调用了两次函数,它们也是不同的?这意味着您无法将存储的密码与您当前正在进行的$p = password_hash($_POST['p'], PASSWORD_DEFAULT,['cost' => 15]);进行比较,因为password_hash()函数每次都返回一个不同的字符串 - 您需要使用函数password_verify()来验证密码,如下所示

$p = $_POST['p'];

if (password_verify($p, $fromDataBase)) {
    // Valid password!
}

所以不是......

$p = password_hash($_POST['p'], PASSWORD_DEFAULT,['cost' => 15]);

你想要

$p = $_POST['p'];

而不是......

if($p != $db_pass_str){

你想要

if (!password_verify($p, $db_pass_str)) {

关于安全的两个注释:

  1. 您没有使用准备好的陈述,真的应该这样做!请参阅下面的mysqli_prepare()链接。您应该将所有用户输入视为危险,因此对所有接受用户输入的SQL查询使用预准备语句。 (当使用准备好的陈述时,你不想使用mysqli_real_escape_string() - 使用一个或另一个,最好是准备好的陈述!)

  2. 您正在会话中存储密码 - 这是非常气馁的,因为会话可以被劫持&#34;。

  3. Readingmaterial: