javascript - Rest API authentication issue when called from fetch request in bundle.js

I'm able to use the Rest API for calls that don't need auth, but I'm having an auth issue for the routes

I'm able to use the Rest API for calls that don't need auth, but I'm having an auth issue for the routes that require it. Here is part of a .php view template for an admin page:

<div id="nonceCreator">
  <script>
    let _wpnonce = <?php echo json_encode(wp_create_nonce('wp_rest')); ?>;

    let cookiesArray = <?php echo json_encode($_COOKIE) ?>;
  </script>
</div>

<div id="reactScriptInjection">
  <div id="adminRoot"></div>
  <script src="<?php echo PLUGIN_FOLDER_URL . "shared/" ?>adminArea.bundle.js"></script>
</div>

The cookies array and nonce seem to pass correctly:

wordpress_69cb7e12fdbb27dfb56056fb4f6b39c8: "<username and long key removed>"
wordpress_logged_in_69cb7e12fdbb27dfb56056fb4f6b39c8: "<username and long key removed>"
wordpress_test_cookie: "WP Cookie check"
wp-settings-1: "unfold=1&mfold=o"
wp-settings-time-1: "1562861991
"=====cookiesArray====="

bac3c6<digits removed> =====_wpnonce=====

The auth request sends back 401 unauthorized however:

Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Object code: "rest_not_logged_in"
data: {status: 401}
message: "You are not currently logged in."
__proto__: Object
"=====response.json()====="

and here is the api call

// from the relevant react.js component's source
const getUserNameFromRestApi = () => {
    console.log(_wpnonce, `=====_wpnonce=====`);

    fetch('http://localhost/wptest2/?rest_route=/wp/v2/users/me', {
      method : 'get',
      mode : 'cors',
      headers : {
        'Access-Control-Allow-Origin' : '*',
        'X-WP-Header' : _wpnonce
      }
    })
      .then(response => console.log(response.json(), `=====response.json()=====`))
      .catch(error => console.log(error, `=====error=====`));
  };

I don't think Access Control Origin plays a factor yet as I'm loading the output bundle.js within an admin page in wordpress.

However, I was able to get another plugin to do a successful authenticated fetch. Only difference was that plugin didn't use react.js, but rather vanilla javascript instead.

I thought cookies might be the problem but you see the $_COOKIE array output above. Also the nonce worked in that other plugin so I think I set it up correctly above too.

What else could it be then? I'm thinking something is wrong with the data flow.

I'm able to use the Rest API for calls that don't need auth, but I'm having an auth issue for the routes that require it. Here is part of a .php view template for an admin page:

<div id="nonceCreator">
  <script>
    let _wpnonce = <?php echo json_encode(wp_create_nonce('wp_rest')); ?>;

    let cookiesArray = <?php echo json_encode($_COOKIE) ?>;
  </script>
</div>

<div id="reactScriptInjection">
  <div id="adminRoot"></div>
  <script src="<?php echo PLUGIN_FOLDER_URL . "shared/" ?>adminArea.bundle.js"></script>
</div>

The cookies array and nonce seem to pass correctly:

wordpress_69cb7e12fdbb27dfb56056fb4f6b39c8: "<username and long key removed>"
wordpress_logged_in_69cb7e12fdbb27dfb56056fb4f6b39c8: "<username and long key removed>"
wordpress_test_cookie: "WP Cookie check"
wp-settings-1: "unfold=1&mfold=o"
wp-settings-time-1: "1562861991
"=====cookiesArray====="

bac3c6<digits removed> =====_wpnonce=====

The auth request sends back 401 unauthorized however:

Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Object code: "rest_not_logged_in"
data: {status: 401}
message: "You are not currently logged in."
__proto__: Object
"=====response.json()====="

and here is the api call

// from the relevant react.js component's source
const getUserNameFromRestApi = () => {
    console.log(_wpnonce, `=====_wpnonce=====`);

    fetch('http://localhost/wptest2/?rest_route=/wp/v2/users/me', {
      method : 'get',
      mode : 'cors',
      headers : {
        'Access-Control-Allow-Origin' : '*',
        'X-WP-Header' : _wpnonce
      }
    })
      .then(response => console.log(response.json(), `=====response.json()=====`))
      .catch(error => console.log(error, `=====error=====`));
  };

I don't think Access Control Origin plays a factor yet as I'm loading the output bundle.js within an admin page in wordpress.

However, I was able to get another plugin to do a successful authenticated fetch. Only difference was that plugin didn't use react.js, but rather vanilla javascript instead.

I thought cookies might be the problem but you see the $_COOKIE array output above. Also the nonce worked in that other plugin so I think I set it up correctly above too.

What else could it be then? I'm thinking something is wrong with the data flow.

Share Improve this question asked Jul 16, 2019 at 12:21 Sean DSean D 3878 silver badges21 bronze badges 5
  • I would strongly advise against putting cookies in a JS array for security reasons, JS can already access cookies directly – Tom J Nowell Commented Jul 16, 2019 at 12:29
  • Good to know, I will look into it. FYI this was just for debugging and the plugin is not public facing yet – Sean D Commented Jul 16, 2019 at 12:37
  • Is that X-WP-Header just a typo in the question? Because it should be X-WP-Nonce .. – Sally CJ Commented Jul 16, 2019 at 13:30
  • 1 @SallyCJ that was indeed the issue, good catch and thanks – Sean D Commented Jul 16, 2019 at 13:45
  • 1 @SallyCJ can you post that as a proper answer so I can upvote? – Tom J Nowell Commented Jul 16, 2019 at 14:06
Add a comment  | 

1 Answer 1

Reset to default 4

The problem is that you're not using the correct name for the REST API nonce header — the correct name is X-WP-Nonce, but you used X-WP-Header:

fetch('http://localhost/wptest2/?rest_route=/wp/v2/users/me', {
  method : 'get',
  mode : 'cors',
  headers : {
    'Access-Control-Allow-Origin' : '*',
    'X-WP-Header' : _wpnonce // here you used the wrong name
  }
})

Reference from the REST API Handbook:

For developers making manual Ajax requests, the nonce will need to be passed with each request. The API uses nonces with the action set to wp_rest. These can then be passed to the API via the _wpnonce data parameter (either POST data or in the query for GET requests), or via the X-WP-Nonce header.

So make sure to use the correct header name. :)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745317688a4622292.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信