【发布时间】:2019-03-14 11:45:38
【问题描述】:
我已经搜索了 SO 内部和外部的线程,但没有解决问题。
背景:使用 PHP、Wordpress 和 ACF(高级自定义字段)创建一个小型登录系统。保存包含密码的帖子后,密码会被散列,并在数据库中替换值。到目前为止一切顺利(据我所知)。当用户访问登录页面,提交密码尝试时,验证 php 文件调用 Wordpress API,检索存储的散列密码,然后运行 password_verify。每次运行时,它都会返回 false。下面的代码...
$pw_submit = $_POST['pw-submit'];
//Call WP API
$urlPrefix = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ?
'https' : 'http';
$siteURL = $urlPrefix . "://" . $_SERVER['SERVER_NAME'];
function callAPI($method, $url, $data){
$curl = curl_init();
$url = sprintf("%s?%s", $url, http_build_query($data));
// OPTIONS:
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:
application/json'));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// EXECUTE:
$result = curl_exec($curl);
if(!$result){die("Connection Failure");}
curl_close($curl);
return $result;
}
$get_data = callAPI('GET', $siteURL . '/wp-json/acf/v3/pages/25', false);
$response = json_decode($get_data, true);
$db_password = $response[acf][portal_password];
if( password_verify( $pw_submit, $db_password) ){
echo "Well that worked";
}
else{
echo "No it didn't";
}
即使我复制/粘贴散列密码并尝试验证,它仍然返回 false...
$hash = '$2y$10$2/PuBIYuhEJ69fSc2/ae.OOVr4nMrpKu.9ahRm90TuSBu0EJulWki';
$verify = password_verify('foobar', $hash);
var_dump($verify);
...它返回 bool(false)。
password_verify 返回 true 的唯一方法是我创建散列密码并立即验证它。所以在验证脚本中...
$pw_hash = password_hash('foobar', PASSWORD_DEFAULT);
$verify = password_verify('foobar', $pw_hash);
var_dump($verify); // Returns TRUE
我检查了数据库并确保表格单元格保存了整个哈希(当我 var_dump 提取的值时,我得到一个 60 个字符的字符串)。我通过使用 trim() 确保之前/之后没有空格。我尝试用单引号替换包含散列字符串的包含双引号。我不知道缺少什么/出了什么问题。非常感谢任何帮助/指导。谢谢!
更新 所以这里的错误是我在修复以前的问题时忘记更新变量。对于那些可能偶然发现这一点的人来说,最初的问题是 Wordpress 运行我的哈希脚本两次,导致第一个哈希密码的哈希值。因此,请始终检查 wordpress 实际在做什么。此外,我遇到的一件事是使用 ACF get_field() 来获取未散列的密码,但是因为我使用的是 wp_insert_post_data() 过滤器,所以我实际上是在获取旧/当前值,而不是获取新/输入密码。通过使用“acf/save_post”过滤器解决了这个问题。谢谢大家的帮助!
【问题讨论】:
-
注意
$db_password = $response[acf][portal_password];应该是$db_password = $response['acf']['portal_password']; -
$2y$10$2/PuBIYuhEJ69fSc2/ae.OOVr4nMrpKu.9ahRm90TuSBu0EJulWki是空字符串的有效哈希。如果那是您的真实数据,请找出它的来源并修复创建它的代码。 -
GrumpyCrouton 谢谢,我已经确认无引号可以正常工作。 @iainn我已经尝试过各种字符串,但如果我当时在那里创建哈希,它似乎只会验证真实。从数据库中提取时,我感觉好像发生了一些事情,但无法弄清楚是什么,因为我尝试了多种方式来清理字符串。
-
我的意思是,您在此处发布的验证码看起来不错,但存储在您的数据库中的哈希值并不是您认为的那样。不管是什么创建的,哈希都没有在正确的字符串上运行——它是一个有效的 bcrypt 哈希,但它是一个空字符串。
var_dump(password_verify('', '$2y$10$2/PuBIYuhEJ69fSc2/ae.OOVr4nMrpKu.9ahRm90TuSBu0EJulWki')); bool(true) -
@iainn 对不起,我误解了你的意思。你是对的!我正在散列一个空字符串。我现在意识到,在最后一天,由于另一个问题,我重新编写了我的哈希脚本,并且错过了变量替换。谢谢!如何将您的评论标记为正确?想确保你得到你的互联网积分:)
标签: php wordpress passwords advanced-custom-fields password-encryption