很晚了,但可能对其他读者有所帮助,因为我专门为这个问题的上述代码添加了解决方案。
解决方案:权限回调函数WordPress: 版本5.7.2PHP: 7.4版host: hostmonster。com
client: Windows 10browsers: 在Chrome、Firefox甚至Edge上进行了测试
Code (PHP 函数中的代码。安装主题的php):
add_action(\'rest_api_init\', function() {
/**
* Register here your custom routes for your CRUD functions
*/
register_rest_route( \'mysite/v1\', \'/ads/\', array(
array(
\'methods\' => WP_REST_Server::READABLE, // = \'GET\'
\'callback\' => \'get_ads\',
// Always allow, as an example
\'permission_callback\' => \'__return_true\'
),
array(
\'methods\' => WP_REST_Server::CREATABLE, // = \'POST\'
\'callback\' => \'create_ad\',
// Here we register our permissions callback
// The callback is fired before the main callback to check if the current user can access the endpoint
\'permission_callback\' => \'prefix_get_private_data_permissions_check\',
),
));
});
// The missing part:
// Add your Permission Callback function here, that checks for the cookie
// You should define your own \'prefix_\' name, though
function prefix_get_private_data_permissions_check() {
// Restrict endpoint to browsers that have the wp-postpass_ cookie.
if ( !isset($_COOKIE[\'wp-postpass_\'. COOKIEHASH] )) {
return new WP_Error( \'rest_forbidden\', esc_html__( \'OMG you can not create or edit private data.\', \'my-text-domain\' ), array( \'status\' => 401 ) );
};
return true;
};
function create_ad() {
global $wpdb;
$result = $wpdb->query(...);
return $result;
}
function get_ads() {
global $wpdb;
$ads = $wpdb->get_results(\'SELECT * from `ads`\');
return $ads;
}
确保在HTML页面中包含
credentials: \'same-origin\'
在HTTP请求中。
Code (HTML 带内联<script> ... </script>
):
<script>
// Here comes the REST API part:
// HTTP requests with fetch() promises
function getYourAds() {
let url = \'https://example.com/wp-json/mysite/v1/ads/\';
fetch(url, {
method: \'GET\',
credentials: \'same-origin\', // <-- make sure to include credentials
headers:{
\'Content-Type\': \'application/json\',
\'Accept\': \'application/json\',
//\'Authorization\': \'Bearer \' + token <-- not needed, WP does not check for it
}
}).then(res => res.json())
.then(response => get_success(response))
.catch(error => failure(error));
};
function insertYourAds(data) {
let url = \'https://example.com/wp-json/mysite/v1/ads/\';
fetch(url, {
method: \'POST\',
credentials: \'same-origin\', // <-- make sure to include credentials
headers:{
\'Content-Type\': \'application/json\',
\'Accept\': \'application/json\',
//\'Authorization\': \'Bearer \' + token <-- not needed, WP does not check for it
},
body: JSON.stringify(data)
}).then(res => res.json())
.then(response => create_success(response))
.catch(error => failure(error));
};
// your Success and Failure-functions:
function get_success(json) {
// do something here with your returned data ....
console.log(json);
};
function create_success(json) {
// do something here with your returned data ....
console.log(json);
};
function failure(error) {
// do something here ....
console.log("Error: " + error);
};
</script>
最终想法:\'Authorization\': \'Bearer \' + token
HTTP请求的标头中是否需要?
经过一些测试,我意识到if ( !isset($_COOKIE[\'wp-postpass_\'. COOKIEHASH] )) { ...
在Permission Callback 不仅检查是否在客户端浏览器上设置了Cookie,but it seems also to check its value (the JWT token).
因为我用我的初始代码进行了dobble检查,传递了一个错误的令牌,消除了cookie,或者让会话保持打开状态,但在后端更改了站点的密码(因此WordPress将创建一个新的令牌,因此set的值wp_postpass_
cookie将更改)并且所有测试都正确进行-REST API blocked, not only verifying presence of cookie, but also its value (这很好-谢谢WordPress团队)。
Sources:
我在FAQ section:
Why is the REST API not verifying the incoming Origin header? Does this expose my site to CSRF attacks?
由于WordPress REST API不验证传入请求的原始标头,因此可以从任何站点访问公共REST API端点。这是一个有意的设计决策。
然而,WordPress有一个现有的CSRF保护机制,该机制使用nonces。
根据我目前的测试,the WP-way of authentication works perfectly well.
为wordpress团队竖起大拇指REST API Handbook:
REST API Handbook / Extending the REST API / Routes and Endpoints
REST API Handbook / Extending the REST API / Adding Custom Endpoints
对于那些对我的发现的完整故事感兴趣的人,请点击链接到我的帖子,并附上答案、代码片段和其他发现。
How to force Authentication on REST API for Password protected page using custom table and fetch() without Plugin