用户登录后,我成功生成了一个nonce,并通过SSL cookie将其传递给客户端:
./functions.php
function set_nonce_cookies(){
$nonce = wp_create_nonce( 'wp_rest');
setcookie( 'my_nonce', $nonce );
}
add_action('wp_login', 'set_nonce_cookies');
然后客户端从 cookie 中获取随机数,并在像这样的测试调用中使用它(其中的变量当然是来自 cookie 的真实值):
$.ajax({
url: apiHost + '/wp/v2/posts',
type: 'POST',
data: {
title: 'Hello World',
content: 'This is my first post!',
status: 'publish'
},
beforeSend: function (xhr) {
xhr.setRequestHeader('X-WP-Nonce', nonce);
},
success: function (response) {
console.log(response);
},
error: function (error) {
console.log(error);
}
});
但我总是并且只收到此错误(尝试在隐身模式下与多个 diff 用户一起尝试):
{
"code": "rest_cookie_invalid_nonce",
"message": "Cookie check failed",
"data": {
"status": 403
}
}
我真的无法弄清楚问题出在哪里。也许随机数无效,但我按照最佳实践生成它。也许它是在错误的时刻生成的(即在用户实际登录之前)?
存在的其他cookies是:
好吧,我自己找到了解决方案。 问题是我只生成一次随机数(在用户登录时,使用过滤器
add_action('wp_login', 'set_nonce_cookies');
,但这个随机数在几秒钟后就过时了。
解决方案是在每次页面刷新时生成随机数,因此在需要时更新 cookie。这是我现在在functions.php中使用的代码行,它的工作方式就像一个魅力:
function set_nonce_cookies(){
$cookie_name = 'rest_nonce';
$cookie_value = wp_create_nonce('wp_rest');
$cookie_exp = 0;
$cookie_path = "/";
$cookie_domain = "";
$cookie_secure = true; //<- This ensures that the SSL protocol is used
$cookie_http_only = false; //<- If true, the cookie cannot be read with JavaScript
setcookie($cookie_name, $cookie_value, $cookie_exp, $cookie_path, $cookie_domain, $cookie_secure, $cookie_http_only);
}
if (is_user_logged_in()) {
set_nonce_cookies();
}