无法将登录密码与数据库中存储的散列密码相匹配

时间:2014-06-27 08:53:54

标签: php mysql hash salt

我是PHP和MYSQL的新手,正在开展注册/登录表单项目以建立我的知识,但我有点卡住了,所以希望你能帮忙。

我在PHPMyAdmin上有一个数据库,我的注册表单会搜索电子邮件地址是否已经存在,如果没有将所有信息插入数据库。这很好用。我还有一个登录表单,搜索电子邮件地址和密码,看看他们是否匹配数据库中的任何一个,如果是这样,登录。这工作正常。

当我开始学习密码盐/散列问题时,我的问题出现了。我仍然可以注册好,但是当我尝试使用数据库中已有的详细信息登录时,它似乎与密码匹配以允许我登录。

register.php

 <?php
error_reporting(E_ALL);
require 'db_connect.php';

// Stores the information submitted from the form via the $_POST variable 
// if the request method in the form is POST then execute the following code (read the                 submitted information - send the email  and redirect to the header location
// if it is NOT POST then it will skip this code block and show blank contact form
if ($_SERVER["REQUEST_METHOD"] == "POST") { 
    $fname = trim($_POST["fname"]);
    $lname = trim($_POST["lname"]);
    $cname = trim($_POST["cname"]);
    $email = trim($_POST["email"]);
    $pass1 = trim($_POST["pass1"]);
    $pass2 = trim($_POST["pass2"]);

// VALIDATIONS


// All required fields must be entered
if ($fname == "" OR $lname == "" OR $email == "" OR $pass1 == "" OR $pass2 == "") {
    $error_message = "You must fill in all the required fields.";

}

// password must contain 6 characters min
if (strlen($pass1) < 6) {
       $error_message = "Password must be at least 6 characters long";

}
//passwords must match each other
if ($pass1 != $pass2) {
   $error_message = "Passwords do not match";
}


// hash and salt password - PASSWORD_DEFAULT uses the php default hashing algorithm - 
// cost is the expense used to generate the hash (higher the number the more secure but slower the page load)

$password_save = password_hash($pass1 . SALT , PASSWORD_DEFAULT, array('cost' => 10 ));

// if there's not a previous error message run a database query to look if the email address entered matches any already in the database.
if (!isset ($error_message)){
  $query = "SELECT * FROM registration_tbl WHERE email = '".$email."'";
  $query_run = mysqli_query($dbc, $query);

  // if the query locates more than 0 (i.e 1+) records with matching email addresses then echo out the error
  // else insert all new form data in to the database and echo a success message      
  if (mysqli_num_rows($query_run)>0) {
       $error_message = "Email Address ".$email." is already registered";
  } else {
    $sql = "INSERT INTO registration_tbl (first_name,last_name,company_name,email,password,reg_datetime) VALUES ('".$fname."','".$lname."','".$cname."','".$email."','".$password_save."', NOW())";
    $query_run = mysqli_query($dbc, $sql);
        echo "Registration Successful";
    }
}

的login.php

<?php
error_reporting(E_ALL);
require 'db_connect.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
$email = trim($_POST["email"]);
$pass = trim($_POST["pass"]);

    // VALIDATIONS

// both fields must be entered to log in        
if($email == "" OR $pass == "") {
    $error_message = "Both fields must be completed ";
}

$hashandsalt = password_hash($pass . SALT, PASSWORD_DEFAULT, array('cost' => 10 ));

// if no error message is set - send a query to the database for all records in the registration_tbl where the email matches one in the database
// if the query returns less than 1 record (i.e no matches in the database) show error message
// else if found in the database save the login details to session variables and then
// redirect to the logged-in.php page   
if (!isset ($error_message)) {
    $query = "SELECT * FROM registration_tbl WHERE email ='".$email."'";
    $query_run = mysqli_query($dbc, $query);
    if (mysqli_num_rows($query_run)<1 ){
        $error_message = "Your login details do not match, please double check and try again1";
    } else {
        while($row = mysqli_fetch_array($query_run)) {
        echo ($row['password']) ."<br>";
        echo $pass ."<br>";
        echo $hashandsalt;

            if (password_verify($pass, $hashandsalt)){
                $_SESSION['firstname'] = $row['first_name'];
                $_SESSION['lastname'] = $row['last_name'];
                $_SESSION['email'] = $row['email'];
                $_SESSION['password'] = $row['password'];
                $_SESSION['id'] = $row['ID'];
                header("location: logged-in.php");
            } else {
                $error_message = "Your login details do not match, please double check and try again";
            }
        }
    }
}
}
?>

<div class="wrapper">

<?php
 if(!isset ($error_message)) {
    echo '<p>Please complete the log in details </p>';
    } else {
    echo $error_message;
 }
?>
<form method="post" action="login.php">
    <table>
        <tr>
            <th>
                <label for="email"> Email Address </label>
            </th>
            <td>
                <input type="email" name="email" id="email" value="<?php if(isset($email)) { echo htmlspecialchars($email); } ?>">
            </td>
        </tr>
        <tr>
            <th>
                <label for="pass"> Password </label>
            </th>
            <td>
                <input type="password" name="pass" id="pass">
            </td>
        </tr>

    </table>
    <input type="submit" value="Log in">
</form>

我在login.php

中有3个回声的结果
echo ($row['password']) ."<br>";

这个将显示数据库中的哈希密码

        echo $pass ."<br>";

这个将显示输入的密码

        echo $hashandsalt;

这个显示一个新的哈希密码,每次刷新页面时都会有所不同

这是我的查询的地方我显然遗漏了一些不允许输入的密码与已存储的哈希密码相匹配的内容。

我已经浏览了互联网,包括堆栈溢出帖子的数量,但我似乎无法弄清楚我做错了什么。这是我的第一篇文章,所以我希望我能为你发布足够的信息。

任何想法的人?

p.s我知道我需要添加mysqli_real_escape_string - 这是我解决这个问题之后的下一个工作:ve

1 个答案:

答案 0 :(得分:2)

要验证密码,您需要使用数据库中存储的密码哈希进行检查。无需在login.php中调用password_hash()

的login.php

if (password_verify($pass, $row['password']))

此外,无需在散列之前添加salt,函数password_hash()将自动添加它。

register.php

$password_save = password_hash($pass1, PASSWORD_DEFAULT, array('cost' => 10 ));
相关问题