WP AJAX:nonce在注销时有效,但在登录时无效

问题描述 投票:3回答:1

我有一个WordPress网站,我正在配置使用jQuery / AJAX查询和加载div框内的帖子。

这是我在functions.php中所拥有的(大规模简化,自然):

function mysite_enqueue_scripts() {
  wp_register_script( 'mysite_front' , get_bloginfo( 'template_url' ) . '/js/front.js' , array( 'jquery' ) );
  wp_enqueue_script( 'mysite_front' ); //loads the front-side jquery
  wp_localize_script( 'mysite_front' , 'AJAX' , array( 
    'ajaxurl' => admin_url( 'admin-ajax.php' ) ,
    'nonce' => wp_create_nonce( 'mysite-ajax-nonce' )
  ) ); //localizes the script
}
add_action( 'wp_enqueue_scripts' , 'mysite_enqueue_scripts' , 100 );
add_action( 'wp_ajax_nopriv_load_items' , 'mysite_ajax_load_items' );
add_action( 'wp_ajax_load_items' , 'mysite_ajax_load_items' );

function mysite_ajax_load_items() {
  if( !check_ajax_referer( 'mysite-ajax-nonce' , 'nonce' , false ) ) {
    wp_send_json( array( 'error' => 'nonce error' ) );
    return;
  } else {
    [[[all the WP query stuff goes here and creates an $html string]]]
    wp_send_json( array( 'html' => $html ) );
  }
}

jQuery front.js

jQuery( document ).ready( function($) {
  $( '#mysite-load' ).click( function() {
    var postData = {
      action : 'load_items' ,
      nonce : AJAX.nonce
    };
    jQuery.post(
      AJAX.ajaxurl , postData , function( response ) {
        if( typeof( response['html'] ) !== 'undefined' ) {
          $( '#mysite-load' ).html( response['html'] );
        } else if( typeof( response['error'] ) !== 'undefined' ) {
          $( '#mysite-load' ).html( 'Error: ' + response['error'] );
        }
      }
    );
  });
});

HTML:

<div id="mysite-load">click</div>

当我没有登录该站点的wp-admin并加载此页面时,一切都运行良好。

但是当我登录网站的wp-admin并加载此页面时,它会返回'nonce error'错误,而不是它应该加载的HTML。

问题不是浏览器特定的;尝试在Safari和Chrome中收到同样的错误。我也尝试使用wp_verify_nonce()而不是check_ajax_referer(),并得到了相同的结果。

知道为什么会这样吗?

php jquery ajax wordpress
1个回答
0
投票

我有这个问题。我发现问题是nonces是以特定的方式处理API AJAX请求。在我的例子中,这是使用自定义端点,但我想它对任何API调用都是一样的。

相关文档在这里:https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/。感兴趣的特定段落在Cookie身份验证下:

对于制作手动Ajax请求的开发人员,需要在每个请求中传递随机数。 API使用nonce,动作设置为wp_rest。然后可以通过_wpnonce数据参数(POST数据或GET请求的查询)或通过X-WP-Nonce标头将这些传递给API。

在实践中,我发现这意味着您必须至少使用动作设置为“wp-rest”的随机数,以确保登录用户在API请求上下文中正确加载。否则,您将使用登录用户生成自定义随机数,但尝试使用匿名用户验证它(除非您使用此随机数,否则这是API调用的默认值)。

$nonce = wp_create_nonce( 'wp_rest' );

然后,您还需要确保通过X-WP-Nonce标头返回通过此操作生成的nonce。

$.ajax({
  type: 'POST',
  url: your-api-url-here,
  contentType: 'application/json; charset=UTF-8',
  beforeSend: function(jqXhr) {
    jqXhr.setRequestHeader('X-WP-Nonce', nonce)
  },
  data: your-data-here
})

(为了清楚起见,我省略了将nonce转移到javascript上下文中的脚本本地化部分,但是你的问题中有那些,所以我假设一切都很好)

完成此操作后,您的AJAX调用将不再是匿名的(如果您已登录),并且您的其他现时将正确验证。

© www.soinside.com 2019 - 2024. All rights reserved.