AJAX插件卸载时check_admin_referer失败,求安全解决方案及对应验证方式
这个问题我之前处理过,确实是WordPress从传统POST转向AJAX操作时常见的安全验证兼容问题,我给你梳理下靠谱的解决方案,既保证高强度安全性又能解决验证失败的问题:
核心解决方案步骤
替换验证函数:用
check_ajax_referer替代check_admin_referer
针对AJAX请求,WordPress专门提供了check_ajax_referer()函数,它比check_admin_referer()更适配AJAX场景——它会自动检测请求中的_wpnonce参数,默认不会像前者那样严格校验HTTP_REFERER头(如果需要也可以通过参数开启,但AJAX场景下通常没必要)。
把你代码里的:check_admin_referer( 'bulk-plugins' );直接替换成:
check_ajax_referer( 'bulk-plugins' );确保AJAX请求正确传递Nonce参数
在触发AJAX卸载的页面(比如插件列表页),你需要生成对应bulk-plugins的nonce值,并在AJAX请求的data里带上它:- PHP端生成nonce:
$bulk_nonce = wp_create_nonce( 'bulk-plugins' ); - JS的AJAX请求中携带参数:
jQuery.ajax({ url: ajaxurl, // WordPress全局的AJAX地址变量 type: 'POST', data: { action: 'bulk-plugins', // 对应WordPress批量插件操作的action标识 action2: 'delete-selected', // 指定操作类型为删除(卸载)选中插件 plugins: ['your-plugin-slug'], // 要卸载的插件slug数组,支持多个 _wpnonce: '<?php echo $bulk_nonce; ?>' // 必须传递的验证nonce }, success: function(res) { // 处理卸载成功后的逻辑,比如刷新插件列表 } });
- PHP端生成nonce:
强化权限检查不能少
不管是传统POST还是AJAX请求,权限检查都是安全的底线。在你的卸载逻辑开头,一定要加上用户权限验证:if ( ! current_user_can( 'delete_plugins' ) ) { wp_die( __( 'You do not have sufficient permissions to delete plugins.' ) ); }对齐原生操作逻辑更稳妥
如果你是自定义AJAX卸载流程,建议参考WordPress原生的wp_ajax_bulk_plugins函数(位于wp-admin/includes/ajax-actions.php)的处理逻辑,确保参数传递、验证步骤和原生行为一致,这样兼容性和安全性都更有保障。
为什么原来的check_admin_referer会失败?
简单说,check_admin_referer()会同时校验两个内容:一是nonce的有效性,二是HTTP_REFERER头是否来自当前站点的后台页面。而AJAX请求的参数传递方式和传统表单提交有差异,该函数的校验逻辑更偏向于普通后台表单;check_ajax_referer()则是专门为AJAX场景设计的,校验逻辑更灵活,更适配AJAX请求的特性。
内容的提问来源于stack exchange,提问作者Szépe Viktor

