我是 PHP 和 MYSQL 的新手,正在做一个注册/登录表单项目来积累我的知识,但我有点卡住了,所以希望你能帮忙。
我在 PHPMyAdmin 上有一个数据库,如果不将所有信息插入数据库,我的注册表会搜索以查看电子邮件地址是否已经存在。这很好用。我还有一个登录表单,用于搜索电子邮件地址和密码以查看它们是否与数据库中的任何匹配,如果是则登录。这工作正常。
当我开始学习密码盐/散列时,我的问题就来了。我仍然可以注册,但是当我尝试使用数据库中已有的详细信息登录时,它似乎与允许我登录的密码不匹配。
注册.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";
}
}
登录.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 的结果
echo ($row['password']) ."<br>";
这将显示来自数据库的散列密码
echo $pass ."<br>";
这个将显示输入的任何密码
echo $hashandsalt;
这个显示了一个新的散列密码,每次刷新页面时密码都不同
这是我的查询所在,我显然遗漏了一些不允许输入的密码与已存储的散列密码相匹配的东西。
我已经搜索了互联网,包括堆栈溢出帖子的数量,但我似乎无法弄清楚我做错了什么。这是我的第一篇文章,所以我希望我为您发布了足够的信息。
有什么想法吗?
p.s 我知道我需要添加 mysqli_real_escape_string - 这是我解决这个问题后的下一份工作:ve
最佳答案
要验证密码,您需要使用数据库中存储的密码哈希值进行检查。无需在 login.php 中调用 password_hash()
。
登录.php
if (password_verify($pass, $row['password']))
另外在散列前不需要加盐,函数password_hash()会自动加。
注册.php
$password_save = password_hash($pass1, PASSWORD_DEFAULT, array('cost' => 10 ));
关于php - 无法将登录密码与数据库中存储的散列密码相匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24447756/