REST API:WP_VERIFY_NONCE()失败,尽管收到正确的随机数值

时间:2019-09-05 作者:Sean D

我正在生成一个nonce,用于对rest api的客户端提取请求:

function prepAllAdminScripts() {
  wp_register_script(
    \'reactAdminArea\'
    , PLUGIN_FOLDER_URL . \'shared/adminArea.bundle.js\'
    , null
    , null
    , true
  );

  wp_localize_script(\'reactAdminArea\', \'serverParams\', [
    \'_wpnonce\' => wp_create_nonce(\'wp_rest\')
    , \'apiBaseUrlFromWp\' => get_rest_url()
  ]);

  wp_enqueue_script(\'reactAdminArea\');
}
add_action(\'admin_enqueue_scripts\', \'prepAllAdminScripts\');
在激发fetch请求时,我看到它进入了auth处理程序函数。nonce值显示为字符串,似乎是匹配的nonce值,但失败:

  protected function authUserOrRespondWithError($clientNonce) { // 3a730<partially removed>
    $verification = wp_verify_nonce($clientNonce); // false

    if ($verification === false) {
      wp_send_json([\'error\' => "Failed nonce verification"]); // sends back to the client
    }
  }
当我在Chrome浏览器控制台中检查nonce值时,它完全匹配。

有人知道为什么这里的验证返回false吗?

Update

下面是我将nonce数据发送回API的方式:

const fetchAllCoupons = async () => {
    try {
      const response = await fetch(`${apiBaseUrl}/pluginFolder/1.0/loadAll`, {
        method : \'post\',
        headers : {
          \'Content-Type\' : \'application/json\'
        },
        body : JSON.stringify({clientNonce})
      });
      let data = await response.json();

      if (data && \'error\' in data) {
        setSnackbarMessage(data.error)
      }

      return data;
    }
    catch (e) {
      console.log(e, `=====error=====`);
    }
  };
以下是路由处理程序:

  public function registerLoadCouponRoute() : void {
    register_rest_route($this->urlBase, \'loadAll\', [
      \'methods\' => [\'get\', \'post\'],
      \'callback\' => [$this, \'respondAllCoupons\']
    ]);
  }
下面是回调的第一部分,其中包含authUserOrRespondWithError:

  public function respondAllCoupons(\\WP_REST_Request $request) {
    global $wpdb;

    $clientNonce = $request->get_param(\'clientNonce\');
    $this->authUserOrRespondWithError($clientNonce);

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

首先,当用户未经过身份验证/登录时,操作的nonce是相同的。(因为用户ID总是0)

其次,你得到false 因为您没有指定nonce动作wp_rest 在您的情况下:

// Correct usage - a valid action name is set (wp_rest).
wp_verify_nonce( $clientNonce, \'wp_rest\' );

// Incorrect usage - empty action; always returns false.
wp_verify_nonce( $clientNonce );
如果您实际尝试使用标准验证请求cookie authentication, 那么你应该使用X-WP-Nonce 发送nonce而不是请求的标头body/有效载荷:

const fetchAllCoupons = async () => {
  try {
    const response = await fetch(`${apiBaseUrl}/pluginFolder/1.0/loadAll`, {
      method: \'post\',
      headers: {
        \'Content-Type\': \'application/json\',
        \'X-WP-Nonce\': clientNonce // <- here, send the nonce via the header
      },
      body: JSON.stringify({
        // WordPress will not use this when verifying the associated user in the request.
        clientNonce,

        // but WordPress will not use this, either. Because we\'re sending a JSON payload.
        _wpnonce: clientNonce
      })
    });
    ...
  } catch (e) {
    ...
  }
};
或者也可以将nonce作为查询字符串(在URL中)发送,如下所示:

`${apiBaseUrl}/pluginFolder/1.0/loadAll?_wpnonce=` + clientNonce

相关推荐

WordPress user Authentication

我目前正在使用WordPress开发一个插件。我创建了一个允许用户注册的注册页面,然后这些信息存储在名为finusers的自定义数据库表中。这就是我目前所做的:下面的代码用于将用户注册到名为finusers的自定义表中。 function db_insert($emailAdd, $password){ global $wpdb, $formErr; if(1 > count($formErr->get_error_messages(