WordPressのREST APIのURLというと、https://example.com/wp-json/wp/v2/usersのように、wp-jsonで始まるURLをご存知の方が多いです。
REST APIが必要ない環境では、このwp-jsonで始まるURLに外部のユーザーがアクセスできるようにしておく必要はありませんから、.htaccessであったり、もしくは、物理的にwp-jsonという名前のフォルダを設置したりして、アクセス制限をしているサイトもあります。
しかし、これは意味がないかもしれませんという話です。
WordPressのREST APIのURLは2つ
タイトルの通り、WordPressのREST APIのエンドポイントURLは2つあります。
- wp-jsonで始まるURL(変更している場合は、変更後のURL)
- rest_routeパラメータ
wp-jsonで始まるURL
1つ目のwp-jsonで始まるURLは知名度が高い。本記事をお読みの方ならご存のことはもちろん、WordPressを長く使っている方なら少しは見たことがあるでしょう。
rest_routeパラメータ
問題は2つ目のREST APIのURLです。実は、WordPressのREST APIにはrest_routeというパラメーターをURLに含めることでもアクセスできます。
このパラメーターはかなり厄介で、https://example.com/?rest_route=/wp/v2/usersのような形でREST APIにアクセスできるのはもちろん、
- https://example.com/contact/?rest_route=/wp/v2/users(投稿や固定ページのURLに付加)
- https://example.com/abc/def/?rest_route=/wp/v2/users(存在しないページに付加)
- https://example.com/?p=1&rest_route=/wp/v2/users(他のパラメーターと同時に指定)
した場合でも、rest_routeというパラメーターをURLに含める限り、REST APIへのアクセスとして扱われるという特徴を持っています。
rest_routeパラメータ経由でのアクセスを制限する方法
これを踏まえると、WordPressのREST APIへのアクセスを正しく制限するには、rest_routeパラメータを使ったアクセスへの制限も必要だと分かります。
つまり、
- .htaccessでwp-jsonを含むURLを404にする設定
- wp-jsonというファイルを作成しておく
といった対策は不十分です。では、どうしたらよいか。
rest_routeパラメーターを無視する
答えは簡単で、rest_routeパラメータを無視するように設定します。テーマのfunctions.phpに次のコードを追記してください。
add_action( 'init', 'ignore_rest_route_parameter' );
function ignore_rest_route_parameter() {
if( isset( $_GET['rest_route'] ) ) {
$_GET['rest_route'] = null;
}
}
たったこれだけで、rest_routeパラメーターが無視されるようになり、rest_routeパラメーター経由でのアクセスはできなくなります。
WordPress側でREST APIへのアクセスを制限している場合は不要
なお、この設定はWordPress側でREST APIへのアクセスを制限している際には不要です。たとえば、
- 特定のプラグイン以外のREST APIを無効にする
- ログインユーザーのみにアクセスを制限する
といった処理をWordPressで(テーマのfunctions.phpやプラグインを用いて)行っているなら、上記のrest_routeを無視する設定は必ずしも必要ありません。
rest_route経由でのREST APIへのアクセスも、WordPressから見ると「wp-json経由でのREST APIへのアクセスと同等」であり、同じように処理されるからです。