WP REST API插件authPermissionCheck()权限检查为何执行两次?
哥们,我之前开发WP REST插件时也碰到过一模一样的问题,这种重复执行大概率是以下几种情况导致的,给你逐一分析:
1. 浏览器的OPTIONS预检请求触发
这是最常见的原因!当你的前端发送非简单请求(比如POST/PUT/DELETE,或者携带自定义请求头)时,浏览器会先自动发送一次OPTIONS预检请求,用来确认服务器是否允许跨域。如果你的authPermissionCheck()绑定到了路由的权限回调,或者全局的REST钩子上,那预检请求会触发一次,实际业务请求又触发一次,就会出现两次执行的情况。
2. 路由被重复注册
如果你的插件代码里不小心多次调用了register_rest_route()注册同一个路由(比如在不同的钩子函数里重复调用,或者没有做重复注册的判断),每个路由实例都会触发权限检查,自然会执行两次。
3. 权限检查方法被重复绑定到钩子
比如你把authPermissionCheck()同时绑定到了rest_pre_dispatch和rest_request_before_callbacks两个钩子,或者多次调用add_action()/add_filter()绑定同一个钩子,都会导致每次请求触发多次权限检查。
4. WordPress内部的二次请求/重定向
如果你的站点permalink设置有问题,或者某些插件/主题导致REST API请求被内部重定向,也会引发两次请求,进而两次执行权限检查。
排查与解决方法
先确认是否是预检请求的问题
打开浏览器开发者工具的网络面板,查看请求记录:如果能看到一条OPTIONS请求和一条实际业务请求(比如POST),那就是预检的锅。解决方法很简单,在权限检查里跳过OPTIONS请求:
function authPermissionCheck($request) { // 跳过OPTIONS预检请求的权限检查 if ($request->get_method() === 'OPTIONS') { return true; } // 你的核心权限检查逻辑 if (!current_user_can('manage_options')) { return new WP_Error('rest_forbidden', __('You do not have permission to access this resource.'), array('status' => 403)); } return true; }
检查路由注册是否重复
搜索你的插件代码,确保register_rest_route()只被调用一次。建议把路由注册放在rest_api_init钩子里,并且可以添加判断避免重复注册:
add_action('rest_api_init', function() { // 先检查路由是否已存在,避免重复注册 if (!get_rest_route(rest_get_server(), '/your-namespace/v1/your-endpoint')) { register_rest_route('your-namespace/v1', '/your-endpoint', array( 'methods' => 'POST', 'callback' => 'your_callback_function', 'permission_callback' => 'authPermissionCheck', )); } });
检查钩子绑定是否重复
确认你只把authPermissionCheck()绑定到了必要的钩子上,比如只绑定到路由的permission_callback,或者只绑定到一个全局REST钩子,避免重复绑定。
排查内部重定向
开启WordPress的WP_DEBUG模式,查看调试日志里是否有重定向相关的提示,或者检查permalink设置是否正确(比如设置为“固定链接”而非“朴素链接”)。
内容的提问来源于stack exchange,提问作者Shotster

