我正在开发一个项目,要求用户使用电子邮件地址和密码登录。这样做,我必须测试该人输入的密码是否与数据库中的密码匹配。我试图以一种我可以使用password_verify()来比较它的方式来获取MySQLi查询(SELECT password FROM users WHERE email='$email_login'
)。我有这个PHP / MySQLi代码:
$email_login = $_POST["email_login"];
$pass_login = $_POST["pass_login"];
if(isset($_POST["email_login"]) && isset($_POST["pass_login"])) {
$sql_query = mysqli_query($conn, "SELECT password FROM users WHERE email='$email_login'");
$pass_query = print_r($sql_query, 1);
echo $pass_query;
$pass_test= password_verify($pass_login, $pass_query);
$sql = mysqli_query($conn, "SELECT id FROM users WHERE email='$email_login' AND password='$pass_test' LIMIT 1");
$userCount = mysqli_num_rows($sql);
if($userCount == 1) {
while($row = mysqli_fetch_array($sql)) {
$id = row["id"];
}
$_SESSION["email_login"] = $email_login;
header("Location: index.php");
exit();
} else {
echo "It looks like you have an issue with your credentials.";
exit();
}
}
数据库架构
--------------------------------------------------------------------
id | first_name | last_name | username | email | password |
1 John Doe john17 john@gmail.com (hashed)
以下是表格:
<h1>Sign in</h1>
<form class="form" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="POST">
<input type="email" name="email_login" size="25" placeholder="Email address" required>
<br>
<br>
<input type="password" name="pass_login" placeholder="Password" required>
<br>
<br>
<input type="submit" name="login" value="Login">
</form>
除了两个password_verify()行之外,一切正常。为了弄清楚出了什么问题,我使用print_r()将$pass_test
变量打印为一个字符串并得到了这个:
mysqli_result Object ( [current_field] => 0 [field_count] => 1 [lengths] => [num_rows] => 1 [type] => 0 )
有没有一种安全的方法可以在一个可以使用password_verify()进行测试的表单中获取mysqli查询的结果?
答案 0 :(得分:1)
您是否注意到while循环内的行缺少'$'符号。
while($row = mysqli_fetch_array($sql)) {
$id = $row["id"];
^ /*missing '$'
}
答案 1 :(得分:0)
快速检查一下,将$pass_login
放在双引号中。请参阅文档中的第一条评论here。
其次,我认为你使这比你需要的更复杂。我认为你所需要的只是:
$pass_login = password_hash ($_POST["pass_login"]);
$sql = mysqli_query($conn, "SELECT id FROM users WHERE email='$email_login' AND password="$pass_login" LIMIT 1");
如果您收到错误的回复,则登录失败,否则。 。
<强>更新强>
所以,既然我已经有更多的时间来看这里,我想出的是一个工作的例子。我已经用面向对象的风格写了这个:
首先,在保存前输入用户哈希密码输入:
$hashed_pass = password_hash("john17", PASSWORD_DEFAULT);
确保您已连接
$conn = mysqli_connect(yadda, yadda, yadda);//obviously, your credentials here
if (!$conn) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
exit;
}
echo "Success: A proper connection to MySQL was made! The my_db database is great." . PHP_EOL;
echo "Host information: " . mysqli_get_host_info($conn) . PHP_EOL;
/*This checks the password on login so as long as your $_POST variables are set from your form you should be all set: */
$_POST["email_login"] = 'john@gmail.com';
$_POST["pass_login"] = "john17";
$email_login = $_POST["email_login"];
$pass_login = $_POST["pass_login"];
if(isset($_POST["email_login"]) && isset($_POST["pass_login"] ) ) {
if ($result = $conn->query("SELECT password FROM test_table WHERE email='$email_login'")) {
printf("Select returned %d rows.\n", $result->num_rows);
$userCount = $result->num_rows;
if($userCount == 1) {
while($user_array = $result->fetch_array()){
//var_dump($user_array);
$saved_hashed_pass = $user_array[0];
$auth = password_verify($_POST["pass_login"], $saved_hashed_pass );
if( $auth === true ) {
echo "It looks like you are approved";
//$_SESSION["email_login"] = $email_login;
//header("Location: index.php");
} else {
echo "It looks like you have an issue with your credentials.";
exit();
}
}
} else {
echo "It looks like you have an issue with your credentials.";
//exit();
}
/* free result set */
$result->close();
} else {
printf("Error: %s\n", $conn->error);
}