REST API中的wp_create_nonce()使User->ID为零

时间:2017-05-11 作者:Dongsan

我有麻烦wp_create_nonce()wp_verify_nonce().

我的问题的根源在于创建nonce的方式和生成nonce的位置。

查看代码wp_create_nonce()wp_verify_nonce(), 我看到nonce是由多个因素创建的哈希值,包括$uid, 这是一个user id of current user.

$user = wp_get_current_user();
$uid = (int) $user->ID;
if ( ! $uid ) {
    /** This filter is documented in wp-includes/pluggable.php */
   $uid = apply_filters( \'nonce_user_logged_out\', $uid, $action );

}
$token = wp_get_session_token();
$i = wp_nonce_tick();
return substr( wp_hash( $i . \'|\' . $action . \'|\' . $uid . \'|\' . $token, \'nonce\' ), -12, 10 ); 
我在REST API下创建nonce,并在普通页面中验证nonce。然而,我也发现$uid 在RESTAPI中变为0(不知道为什么,但我在某处看到了这一点并亲自测试了它。是的,REST中没有用户id)。所以$uid 在我的休息功能和$uid 在我的页面中变得不同。

[1] 我创建_wpnonce 在REST API中。下面是我在REST中的函数的伪代码。

add_action( \'rest_api_init\', function() {
    register_rest_route( \'view/\', \'/customers/\', array(
        \'methods\' => \'POST\',
        \'callback\' => \'fnc_view_customer_in_table_format\'
    ));
});

if( !function_exists( \'fnc_view_customer_in_table_format\' ) ) {
    function fnc_view_customer_in_table_format(WP_REST_Request $request ) {

    //*** Code omitted on purpose ***

    $data .= \'<form action="\'. get_the_permalink( $post->ID ) .\'" id="_form-view" name="_form-view" method="post">\';
    $data .= \'<input type="hidden" id="_wpnonce" name="_wpnonce" value="\'. wp_create_nonce( \'view_post-\'. $post->ID ) .\'" />\';
    $data .= \'<input type="hidden" id="_post_id" name="_post_id" value="\'. $post->ID. \'" />\';
    $data .= \'<input type="submit" class="btn btn-sm btn-link" value="\'. get_the_title( $post->ID ) .\'">\';
    $data .= \'</form>\';

    //*** Code omitted on purpose ***

    $result = array( \'msg\' => $data, \'error\' => false );
}
【2】以上$data 作为响应返回,并在正常页面中回显。我在这里验证nonce。这是一个普通的wordpress页面。

<?php
get_header();

$wpnonce = $_REQUEST[\'_wpnonce\'];
$post_id = $_REQUEST[\'_post_id\'];
if( !wp_verify_nonce( $wpnonce, \'view_post-\'. $post_id ) ) {
    die( \'Security check\' );
}

?>

//*** Omitted: HTML Codes ***

<?php
get_footer();
因此,我假设唯一的解决方案是让Wordpress REST识别当前的\\u用户。我是如何做到这一点的,还是我的想法是错误的?

**编辑**作为解决方法,我更改了wp_verify_nonce 处理如下。

// nonce is created in REST API, which doesn\'t have UID
// In order to replicate the same, set UID to 0 here
$uid = (int) wp_get_current_user()->ID;
wp_set_current_user(0);

// Nonce check
if( !wp_verify_nonce( $wpnonce, \'view_post-\'. $post_id ) ) {
die( \'Security check\' );
}

// Now get the current user back in place
wp_set_current_user( $uid );
不管怎样,这看起来并不漂亮。有什么更好的做法可以解决我的问题?

1 个回复
SO网友:Kangulo

我知道这个问题已经过去很久了。

但我也有同样的问题,我很难找到一些关于它的文档。我也有同样的问题,出于某种原因,wp\\u create\\u nonce和wp\\u verify\\u nonce无法检索不同的哈希。所以我注意到问题是这两个函数用来散列nonce的$User->ID或$uid。

我只是试图在脚本中创建nonce,但由于某种原因,uid变为0,我所做的是在脚本块之前和之外创建nonce,并在脚本中打印值。

首先是这样(错误):

  var action     = \'submit_user_review\';                  
  var ajax_nonce = \'<?php echo wp_create_nonce(\'security\'); ?>\';

  jQuery.ajax({
       url: my_ajax_object.ajax_url,
       type: \'POST\',
       data: {
           action: action,
           listing_id: rest_id,
           review: comment,
           rate: rate,
           security_review: ajax_nonce,
       },
       beforeSend: function() {
           // Show full page LoadingOverlay
           jQuery.LoadingOverlay("show");
      },            
在这样之后(很好):

  <?php //Set Your Nonce
      $ajax_nonce_review = wp_create_nonce( "submit-user-review" );
  ?>
  <script>                  
  var action = \'submit_user_review\';

  jQuery.ajax({
       url: my_ajax_object.ajax_url,
       type: \'POST\',
       data: {
           action: action,
           listing_id: rest_id,
           review: comment,
           rate: rate,
           security_review: \'<?php echo $ajax_nonce_review; ?>\',
       },
       beforeSend: function() {
           // Show full page LoadingOverlay
           jQuery.LoadingOverlay("show");
      }, 
这就解决了我的问题,真的花了一天的时间来解决这个问题。

我希望它能帮助别人。

结束

相关推荐

在AJAX插入后初始化TinyMCE编辑器/可视化编辑器

我在自定义选项页面上有一个“repeater”样式的字段组。有一个处于隐藏状态的活动可视化编辑器,当用户单击“添加新内容”时,整行将被克隆。然后,我需要初始化克隆行中的可视化编辑器。我的代码:$(\'.repeater-add-new\').click(function(event) { event.preventDefault(); var target = $(this).data(\'repeater\'); $( \'#\' + target).fi