認証

2020.03.24 2020.03.24

TOPICS

Cookie認証

Cookie認証とは、WordPressに標準で搭載されている認証方法です。ダッシュボードにログインすると、これが正しくCookieを設定してくれるので、プラグインやテーマの開発者はログインしているユーザーだけで済みます。

しかし、REST API には CSRF の問題を回避するための nonces と呼ばれるテクニックが含まれています。これにより、他のサイトが明示的に意図せずにアクションを実行させることを防ぐことができます。このため、API には少し特殊な処理が必要になります。

ビルトインのJavascript APIを使用している開発者の場合は、自動的に処理されます。プラグインやテーマでAPIを使用する場合は、この方法が推奨されます。カスタムデータモデルは、wp.api.models.Baseを拡張して、カスタムリクエストに対してこれが正しく送信されるようにすることができます。

手動で Ajax リクエストを行う開発者の場合は、リクエストごとに nonce を渡す必要があります。API は、アクションが wp_rest に設定されている nonce を使用します。これらは、_wpnonce データパラメータ (POST データか GET リクエストのクエリのいずれか) あるいは X-WP-Nonce ヘッダを使用して API に渡すことができます。nonce が提供されない場合、API は現在のユーザーを 0 に設定し、WordPress にログインしていても認証されていないリクエストになります。

注意: 最近まで、ほとんどのソフトウェアでは DELETE リクエストをサポートしていませんでした。たとえば、PHP は DELETE リクエストのリクエストボディをスーパーグローバルに変換しません。そのため、ヘッダとして nonce を指定するのが最も信頼性の高い方法です。

この認証方法は、WordPress の Cookie に依存していることを覚えておくことが重要です。その結果、この方法は WordPress 内部で REST API を使用し、現在のユーザーがログインしている場合にのみ適用されます。さらに、現在のユーザーは、実行中のアクションを実行するための適切な権限を持っている必要があります。

例として、組み込みの Javascript クライアントが nonce を作成する方法を示します。

<?php
wp_localize_script( 'wp-api', 'wpApiSettings', array(
    'root' => esc_url_raw( rest_url() ),
    'nonce' => wp_create_nonce( 'wp_rest' )
) );

これが以下のように、ベースモデルで使用されます。

options.beforeSend = function(xhr) {
    xhr.setRequestHeader('X-WP-Nonce', wpApiSettings.nonce);
 
    if (beforeSend) {
        return beforeSend.apply(this, arguments);
    }
};

以下は、jQuery AJAXを使用して記事のタイトルを編集する例を示します。

$.ajax( {
    url: wpApiSettings.root + 'wp/v2/posts/1',
    method: 'POST',
    beforeSend: function ( xhr ) {
        xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
    },
    data:{
        'title' : 'Hello Moon'
    }
} ).done( function ( response ) {
    console.log( response );
} );

カスタムエンドポイント内で nonce が有効であることを確認する必要はないことに注意しましょう。これはrest_cookie_check_errors()で自動的に行われます。

訳者のQiitaの記事でも解説していますので、もしよければ読んでみてください。(ちょっと自信ないけど…)

認証プラグイン

Cookie 認証は WordPress 内でネイティブに利用可能な唯一の認証メカニズムですが、リモートアプリケーションから動作する代替の認証モードをサポートするためにプラグインを追加することもできます。プラグインの例としては、OAuth 1.0a ServerApplication PasswordsJSON Web Tokens などがあります。

Basic Authenticationのプラグインもあります。
このプラグインはリクエストのたびにユーザー名とパスワードを送信する必要があり、開発とテストのためだけに使用されるべきであることに注意してください。