WordPress:AJAX调用REST API时Cookie校验失败问题求助
我搭建了一个页面加载时自动通过AJAX调用的REST API,用于获取文章元数据。为保证安全,设置了permission_callback限制仅管理员用户可访问,但调用时一直返回rest_cookie_invalid_nonce错误。如果注释掉权限回调和请求里的X-WP-Nonce,API能正常响应,但get_current_user_id()返回0,无法验证管理员身份。需要实现的目标:已登录的管理员用户在页面加载时能正常调用API,同时权限控制生效。
原代码
// register rest api route add_action('rest_api_init', 'register_api_endpoints'); function register_api_endpoints() { register_rest_route('api/v1/', '/getdata/', array( 'methods' => 'GET', 'callback' => 'rest_api_callback', 'args' => array( 'id' => array( 'required' => true, ), ), 'permission_callback' => 'check_permission', )); } //check user permission callback function check_permission() { return current_user_can('administrator'); } function enqueue_custom_scripts() { wp_enqueue_script('jquery'); $inline_nonce = wp_create_nonce('my_inline_nonce'); wp_localize_script('jquery', 'my_ajax_object', array('ajax_nonce' => $inline_nonce)); } // Function to enqueue scripts with nonce add_action('wp_enqueue_scripts', 'enqueue_custom_scripts'); // Hook the ajax functionality to the wp_footer action add_action('wp_footer', 'get_ajax_html'); function get_ajax_html() { $html = '<script> jQuery.ajax({ url: "/wp-json/api/v1/getdata?id=1", method: "GET", headers: { "X-WP-Nonce": my_ajax_object.ajax_nonce, }, contentType: "application/json; charset=utf-8", dataType: "json", }) </script>'; echo $html; } // rest api callback function rest_api_callback($data) { //get current user id $user_id = get_current_user_id(); $post_id = sanitize_text_field($data['id']); $result = get_post_meta($post_id); if (!empty($result)) { return rest_ensure_response($result); } else { return new WP_Error('empty', 'No results found', array('status' => 404)); } }
错误信息
{ "code": "rest_cookie_invalid_nonce", "message": "Cookie check failed", "data": { "status": 403 } }
解决方案
1. 修正Nonce的创建逻辑
WordPress REST API默认使用wp_rest作为nonce验证的action名称,自定义的my_inline_nonce不匹配导致验证失败。修改enqueue_custom_scripts函数:
function enqueue_custom_scripts() { wp_enqueue_script('jquery'); // 使用REST API默认的nonce action $rest_nonce = wp_create_nonce('wp_rest'); // 传递正确的REST API地址,避免硬编码 wp_localize_script('jquery', 'my_ajax_object', array( 'ajax_nonce' => $rest_nonce, 'rest_url' => get_rest_url(null, 'api/v1/getdata') )); }
2. 优化权限回调函数
先验证用户是否登录,再检查管理员权限,避免未登录用户触发无效验证:
function check_permission() { return is_user_logged_in() && current_user_can('administrator'); }
3. 修正AJAX请求写法
- 用
my_ajax_object.rest_url替代硬编码地址,适配不同环境 - GET请求无需设置
contentType: "application/json",改用data参数传递id更规范:
function get_ajax_html() { $html = '<script> jQuery.ajax({ url: my_ajax_object.rest_url, method: "GET", headers: { "X-WP-Nonce": my_ajax_object.ajax_nonce, }, dataType: "json", data: { id: 1 }, success: function(response) { console.log("获取到的数据:", response); }, error: function(xhr) { console.error("请求错误:", xhr.responseJSON); } }) </script>'; echo $html; }
4. 确保登录状态传递
管理员登录后,WordPress会自动设置wordpress_logged_in_开头的cookie,AJAX请求会自动携带这些cookie,配合正确的nonce就能验证用户身份,此时get_current_user_id()会返回当前管理员ID,权限验证生效。
修改后的完整代码
// register rest api route add_action('rest_api_init', 'register_api_endpoints'); function register_api_endpoints() { register_rest_route('api/v1/', '/getdata/', array( 'methods' => 'GET', 'callback' => 'rest_api_callback', 'args' => array( 'id' => array( 'required' => true, 'sanitize_callback' => 'sanitize_text_field' ), ), 'permission_callback' => 'check_permission', )); } //check user permission callback function check_permission() { return is_user_logged_in() && current_user_can('administrator'); } function enqueue_custom_scripts() { wp_enqueue_script('jquery'); $rest_nonce = wp_create_nonce('wp_rest'); wp_localize_script('jquery', 'my_ajax_object', array( 'ajax_nonce' => $rest_nonce, 'rest_url' => get_rest_url(null, 'api/v1/getdata') )); } add_action('wp_enqueue_scripts', 'enqueue_custom_scripts'); add_action('wp_footer', 'get_ajax_html'); function get_ajax_html() { $html = '<script> jQuery.ajax({ url: my_ajax_object.rest_url, method: "GET", headers: { "X-WP-Nonce": my_ajax_object.ajax_nonce, }, dataType: "json", data: { id: 1 }, success: function(response) { console.log("获取到的数据:", response); }, error: function(xhr) { console.error("请求错误:", xhr.responseJSON); } }) </script>'; echo $html; } // rest api callback function rest_api_callback($data) { $user_id = get_current_user_id(); // 可通过错误日志验证用户ID是否正确获取 error_log('当前登录用户ID:' . $user_id); $post_id = $data['id']; $result = get_post_meta($post_id); if (!empty($result)) { return rest_ensure_response($result); } else { return new WP_Error('empty', 'No results found', array('status' => 404)); } }
内容的提问来源于stack exchange,提问作者Sujan Shrestha
相关产品推荐
相关产品推荐

