我似乎无法解决为什么password_verify不起作用。上传的密码都是哈希值。使用PDO进行密码验证没有返回任何内容,我已将密码上传页面添加到底部,因为这里可能存在问题?根据我的理解,当我在错误日志中运行时,$ hash目前没有任何价值。如果密码验证工作不正常或我的代码中有错误,我不是用户。我很感谢你的帮助。
if (isset($_POST['submit'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$q = $handler->prepare('SELECT * FROM users WHERE username = ?');
$q->execute(array($username));
$result = $q -> fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE) {
$hash_pwd = $result['password'];
$hash = password_verify($hash_pwd, $password);
error_log($password);
error_log($username);
error_log($hash_pwd);
//error_log($hash);
//error_log((int) $hash);
if ($hash) {
$username = $_SESSION['username'];
error_log("loggedin");
header("location:index.php");return;
}
else {
echo '<p class="error-message3"><br><br>You have ented an incorrect login!<br>Please try again</p>';
}
}
}
?>
if
(isset($_POST['username']) && isset($_POST['password']))
{
if (empty($_POST['username']) || empty($_POST['password'])) {
echo('<p class="error-message2">'.'Please Fill All Boxes'.'</p>');
}
else {
$username = $_POST['username'];
$password = password_hash($pass, PASSWORD_DEFAULT);
$sql = "INSERT INTO users (username, password) VALUES (:username, :password)";
$query = $handler->prepare($sql);
$query->execute(array(
':username' => $username,
':password' => $password,
));
echo('<p class="error-message2">'.'Thank You For Your Submission!'.'</p>');
}
}
?>
答案 0 :(得分:1)
根据原始问题中的代码和评论中的代码,您似乎正确使用了password_hash()
和password_verify()
,并且无法检测到代码整体结构的另一个明显错误,所以我怀疑数据本身有些奇怪。
例如,您的SELECT
可能会返回多行(如果您未在username
列上设置唯一索引,则可能有两个用户具有相同的{ {1}},但不同的username
- 您没有向我们展示表结构/索引。)
为了进一步调试,我建议改变你的代码:
password
请告诉我们if (isset($_POST['submit'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$q = $handler->prepare('SELECT * FROM users WHERE username = ?');
$q->execute(array($username));
if ($q->rowCount() > 0){
error_log((string) ($q->rowCount()));
$result = $q -> fetch(PDO::FETCH_ASSOC);
$hash_pwd = $result['password'];
$hash = password_verify($password, $hash_pwd);
error_log($hash_pwd);
error_log($hash);
error_log((int) $hash);
if ($hash == 0) {
error_log("hashwrong");
echo '<p class="error-message3">'.'<br>'.'<br>'."You have ented an incorrect login! <br>Please try again.".'</p>';
}
else {
$_SESSION['username'] = $username;
error_log("loggedin");
header("location: index.php");return;
}
}
}
语句转出的内容。为了使其可读,您可以编辑您的问题并在结尾追加结果(而不是将其放入评论中)。但是请不要改变已经被评论或答案引用的问题的那些部分(否则,后来的读者将无法从中获得任何意义)。
编辑1
我注意到代码中可能存在错误。我没有立即看到它的原因是我从未使用过PHP。
但是,您应该不使用error_log()
来检查::rowCount()
语句是否返回任何行。来自::rowcount reference in the PDO manual:
PDOStatement :: rowCount()返回受影响的行数 最后由相应的DELETE,INSERT或UPDATE语句执行 PDOStatement对象。
如果关联的PDOStatement执行的最后一条SQL语句是 一个SELECT语句,一些数据库可能会返回行数 由该声明返回。但是,不保证这种行为 适用于所有数据库,不应依赖于便携式数据库 应用
另一方面,从PDO手册中的::fetch reference:
此函数的成功返回值取决于获取 类型。在所有情况下,失败时都会返回FALSE。
那么请你删除现有的行
SELECT
并替换
$result = $q -> fetch(PDO::FETCH_ASSOC);
通过
if ($q->rowCount() > 0) {
并告诉我们结果?
如果这不记录任何错误消息(PHP警告除外),那么我们知道$result = $q -> fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE) {
由于某种原因没有返回任何行。请记住,根据上面显示的手册部分,SELECT
可能没有返回行,但SELECT
仍然大于0。
如果仍然记录错误消息,我们将不得不进行额外的调试。
编辑2
我们现在知道您的$q->rowCount()
会返回一行,并且获取数据没有问题。现在我自己用完了选项。
SELECT
确实是错误的(从代码的角度来看)。如果POST请求的编码错误,最终可能会发生这种情况。要做出决定,我们可以执行以下步骤:
1)出于测试目的,将新用户插入$password
表。此用户的users
和username
应仅包含ASCII范围内的字符。例如,选择password
作为用户名(在'AAAAA...'
唯一后添加'A'
个字符),将username
添加为'B'
。
然后使用password
/ username
再次运行您的脚本,并告诉我们发生了什么。
此测试的意义在于防止因不适当的字符串/ POST数据编码/解码而可能出现的问题。
2)在代码中再插入两行:
password
将这些行放在其他error_log($username);
error_log($password);
调用所在的相同位置,并检查这是否确实输出了您所期望的内容,即确切地和字面上输出到脚本的值(即您拥有的值)在提交之前输入您的表格。)
让我们知道这两行输出的内容。
3)如果1.中描述的测试有效:
确保调用脚本的HTML页面已明确设置正确的编码。例如,有类似
的内容error_log()
HTML标题中的(请注意,这适用于XHTML; HTML 5或HTML 4.x的语法或标题可能不同;您必须对其进行研究。)
请告诉我们当时会发生什么。
4)如果1.中描述的测试有效:
我不知道您实际上是如何调用该脚本的,但无论如何,在调用脚本时还要另外设置正确的编码。例如,如果您通过AJAX调用脚本,请执行类似
的操作<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />;
如果你直接打电话&#34;直接&#34;从表单中,然后执行类似
的操作request.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
请告诉我们当时会发生什么。
5)如果1.中描述的测试有效:
确保您的网络服务器不会覆盖HTML网页中设置的编码。配置服务器的方式取决于服务器软件。对于Apache,禁用所有<form method="post" enctype="..." accept-charset="UTF-8">
指令(通过注释掉它们)。
请告诉我们当时会发生什么。
编辑3
错误在上传代码中。您在AddDefaultCharset
中使用$pass
,但hash_password()
未在任何地方初始化。所以只需添加
$pass
在现有的行
之后$pass=$_POST['password'];
然后创建一个新的$username=...;
/ username
组合并尝试使用您当前的登录代码登录(但请记住再次检查password
的参数是否顺序正确)。它应该工作。
答案 1 :(得分:0)
手册:
boolean password_verify ( string $password , string $hash )
您的代码:
$hash = password_verify($hash_pwd, $password);
您只是将两个参数反转为password_verify
!