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

时间:2017-01-26 16:30:29

标签: php jquery ajax wordpress

我有一个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(),并收到相同的结果。

知道为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

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

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

  

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

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

$nonce = wp_create_nonce( 'wp_rest' );

然后,您还需要确保通过X-WP-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
})

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

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