duanchun2349 2016-09-15 21:04
浏览 52
已采纳

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

I have added the password_hash PHP function to my registration page, where users create accounts and store passwords. I applied the same password_hash line of code in the registration form. The data is saved in the database, but when I try to log in, the password submitted isn't matching the password stored. I also tried the password_verify function, which I read in the PHP manual, but nothing works. I really don't know what else to do, after trying and trying, so if anybody has an advice, I'd appreciated it.

P.S. I'm currently using PHP version 5.6.25.

Here's the code:

<?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:

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条回答 默认 最新

  • duano3557 2016-09-15 21:17
    关注

    Your understanding of how password_hash() works is a bit off. Unlike using sha1() or md5() (both of which you should avoid for storing passwords!), the password_hash() doesn't return the same string for every time it's called, even for the same string.

    For example:

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

    would output (for example, the strings returned by password_hash() varies for each time its called)

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

    Notice that they are different, even when the function is called twice on the same value? This means, that you cannot compare the stored password against $p = password_hash($_POST['p'], PASSWORD_DEFAULT,['cost' => 15]); like you are currently doing, because the password_hash() function returns a different string every time - you need to use the function password_verify() to verify the password, like below

    $p = $_POST['p'];
    
    if (password_verify($p, $fromDataBase)) {
        // Valid password!
    }
    

    So instead of...

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

    you want

    $p = $_POST['p'];
    

    and instead of...

    if($p != $db_pass_str){
    

    you want

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

    And two notes on security:

    1. You are not using prepared statements, which you REALLY should! See a link for mysqli_prepare() below. You should treat all your user-input as dangerous, and therefor use prepared statements for all SQL queries that accepts user-input. (When using prepared statements, you don't want to use mysqli_real_escape_string() - use one or the other, most preferably prepared statements!)

    2. You are storing a password in a session - this is highly discouraged, as sessions can be "hijacked".


    Readingmaterial:

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)
  • ¥20 matlab yalmip kkt 双层优化问题
  • ¥15 如何在3D高斯飞溅的渲染的场景中获得一个可控的旋转物体
  • ¥88 实在没有想法,需要个思路
  • ¥15 MATLAB报错输入参数太多
  • ¥15 python中合并修改日期相同的CSV文件并按照修改日期的名字命名文件
  • ¥15 有赏,i卡绘世画不出
  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入