LoginSignup
5
5

More than 3 years have passed since last update.

WordPressのAPIでログインしてるかチェックしたい

Posted at

はじめに

WordPressで独自APIを作ったときなどで、ログインしているユーザーにしか叩いて欲しくないAPIありますよね。
最初は、APIのコードの中でis_user_logged_in()とかやって、ログインしてなかったら弾けばいいや。と思ってましたが、話はそう簡単ではなかった。

WP REST APIの公式の認証の「クッキー認証」ところを読みましたが、結構ハマったので書いておきます。

ちなみに、ここに書いた方法が正しいかどうかはよくわからないけどね...

独自APIの作り方はこちらを参考にしています。

流れ

APIの中ではユーザーがログインしているかどうかは判定できません。(なんでかは分からんけど)
というわけで、WordPressのnonceを使用して、APIを叩く権限があるかどうかチェックしていきます。

今回は管理画面でのみ使用できるAPIを想定して説明します。

nonceを作成


//管理画面用のcssとjsを読み込む
add_action( 'admin_enqueue_scripts', 'load_custom_wp_admin_style' );

function load_custom_wp_admin_style($hook) {
    $apiArgs = [
        'root' => esc_url_raw( rest_url() ), //APIのルートURLが入ってます
        'nonce' => wp_create_nonce( 'wp_rest' ) //nonceの名前は「wp_rest」にします
    ];

    wp_enqueue_script( 'master-js', plugins_url('master.js', __FILE__), ['jquery'], '1.0');
    wp_localize_script( 'master-js', 'WP_API_Settings', $apiArgs );
}

解説

wp_enqueue_scriptの第一引数と、wp_localize_scriptの第一引数を揃えます。
ここで、どのjsファイルに紐付けるか設定しています。

wp_localize_scriptの第二引数WP_API_Settingsは、その名前でオブジェクトを作成しますよと言っています。
wp_localize_scriptの第三引数で、オブジェクトに設定したい値を入れています。

今回は、「wp_rest」という名前でnonceを作成しました。

管理画面の対象のページに移動して、ページのソースを表示して、WP_API_Settingsで検索してみてください。

wp-api-setting-2.png

このような感じで変数が出力されていると思います。
変数が出力されていなかったら、どこか間違っていますので修正してください。

nonceをjs側で使用

続いて、JavaScript側に移ります。


$.ajax({
    url: WP_API_Settings.root + '/wp/v2/test_api',
    type: 'POST',
    beforeSend: function ( xhr ) {
        xhr.setRequestHeader( 'X-WP-Nonce', WP_API_Settings.nonce );
    },
    data: saveData,
})
.done( (data) => {
    alert('成功しました')
})
.fail( (data) => {
    alert('失敗しました')
})

解説

先程、wp_localize_scriptで作成したwp_localize_scriptを使用しています。
nonceは、beforeSendを使ってHTTPのヘッダーとして渡します。

nonceをphp側でチェック

function test() {
    $response = new WP_REST_Response();

    $nonceResult = wp_verify_nonce($_SERVER['HTTP_X_WP_NONCE'], 'wp_rest');
    if(!$nonceResult) {
        $response->set_status(403);
        return $response;
    }
}

解説

wp_verify_nonceでnonceが正しいかチェックしています。

js側でヘッダーにセットした値は、$_SERVER['HTTP_X_WP_NONCE']で取得します。
※php側で受け取るときは、なぜかすべて大文字になりますのでご注意。

最初にwp_restという名前で、nonceを作成したので、同じ名前でチェックします。

まとめ

だいたいWordPressのAPIといえば、記事の取得とか誰が叩いてもOKなのが多いんですけど、そうでない場合もたまにありました。
全部のAPIが管理者しか叩けないようにしたい場合は、APIのフックがあって、そこで管理者かどうかのチェックを入れるコードもググったら出てきました。

途中で諦めそうになった...

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5