web-dev-qa-db-ja.com

bundle.jsのフェッチ要求から呼び出されたときのAPI認証の問題を解決する

認証を必要としない呼び出しにRest APIを使用できますが、認証を必要とするルートで認証の問題が発生しています。管理ページの.phpビューテンプレートの一部を次に示します。

<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>

クッキーの配列とノンスは正しく通過するようです:

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=====

ただし、認証リクエストは401を無許可で送り返します。

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()====="

そして、これがAPI呼び出しです

// 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=====`));
  };

ワードプレスの管理ページ内で出力bundle.jsをロードしているので、Access Control Originはまだ要素を果たしているとは思いません。

しかし、認証されたフェッチを成功させるために別のプラグインを取得することができました。唯一の違いは、プラグインがreact.jsを使用せず、代わりにVanilla javascriptを使用したことです。

Cookieが問題である可能性があると思いましたが、上記の$ _COOKIE配列の出力が表示されます。 nonceは他のプラグインでも機能したので、上でも正しく設定したと思います。

それでは、他に何ができるでしょうか?データフローに問題があると思います。

2
Sean Dezoysa

問題は、REST API nonceheaderに正しい名前を使用していないことです。正しい名前はX-WP-NonceX-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
  }
})

REST APIハンドブック からの参照:

手動のAjaxリクエストを行う開発者の場合、ノンスはリクエストごとに渡す必要があります。 APIはアクションをwp_restに設定してナンスを使用します。これらは、_wpnonceデータパラメータ(POSTデータまたはGETリクエストのクエリ内)を介して、またはX-WP-Nonce header

したがって、必ず正しいヘッダー名を使用してください。 :)

4
Sally CJ