wordpress verify_nonce 未登录时不工作

wordpress verify_nonce not working when not logged in

我正在为我网站的访问者构建一个带有登录表单的自定义 Wordpress 主题。该表单有一个用户名、密码字段、一个隐藏的随机数字段和一个隐藏的操作字段。提交时,表单会发送到 wp-admin/admin-post.php,我将自定义函数挂接到其中,以处理登录提交。

如果我只在自定义登录功能中获取用户名和密码,然后将它们插入 wp_signon(),一切正常,用户可以登录。但是,如果我尝试使用验证随机数wp_verify_nonce($nonce,$action),它 returns 错误。我使用 wp_create_nonce($action) 创建了随机数。我验证了登录函数在 $_POST 变量中接收到的随机数与我创建的随机数相同,并且我插入验证函数的操作也与我插入创建的操作相同功能。

我还有一个注销功能,可以通过 mydomain/wp-admin/admin-post.php?action=action&nonce=nonce 的获取请求访问。在处理此请求的自定义注销函数中,我以完全相同的方式检查随机数,但在这里它工作正常。当用户尚未登录时,我是否需要做一些不同的事情来创建随机数?我认为 nonce 是基于 userID 的哈希和一些时间信息,但是由于在创建和验证 nonce 时用户 ID 都是 0(未登录),我不明白为什么这行不通。

我的functions.php中的自定义登录功能供参考。 echo 语句 returns 是正确的随机数,但 $nonceResult 是错误的。

function handle_customer_login() {
    $username = $_POST['username'];
    $password = $_POST['password'];
    $nonce = $_POST['_nonce'];
    $nonceResult = wp_verify_nonce($nonce,'customer_login');

    if (empty($_POST['_nonce'])) {
        echo 'error: ';
        var_dump($nonceResult);
        die();
    } else {
        echo 'nonce: '.$_POST['_nonce'];
        var_dump($nonceResult);
        die();
    }
}
add_action('admin_post_customer_login','handle_customer_login'); 
add_action('admin_post_nopriv_customer_login','handle_customer_login'); 

我在下面的代码行中创建了随机数,并将 $login_nonce 添加到 wp_localize_script() 函数以将其传递给 javascript。然后我使用 javascript 呈现登录表单,其中随机数在隐藏字段中显示得很好。

$login_nonce = wp_create_nonce('customer_login');

我自己找到了解决办法。也许这会帮助某人。我查看了创建 nonce 的函数和验证它的函数。两者都采用一些变量(nonce tick、user id、session token、action)并创建一个散列,其最后的索引成为 nonce。如果您验证请求提供的 nonce,则会根据这些输入变量重新创建 nonce,如果相同,则它是有效的。

如果没有登录用户,将根据使用 'nonce_user_logged_out' 过滤器 (apply_filters( 'nonce_user_logged_out', $uid, $action );) 过滤用户 ID 和操作来创建虚假用户 ID。我在创建和验证时检查了哪些函数被挂接到这个过滤器步骤中。事实证明,在验证期间没有函数挂钩,但 nonce_user_logged_out 在创建期间被挂钩。我能够通过在 运行 wp_verify_nonce 之前使用 add_filter() 添加 'nonce_user_logged_out' 过滤器来解决问题。