WordPress4.7 の WP REST API を無効にする


WordPress4.7 から「WP REST API」が使えるようになりました。
「WP REST API」は デフォルトで有効になっていて 特定のURLで投稿記事やユーザー情報等、認証無しでもさまざまなデータを外部から取得する事ができます。

これはすばらしい機能なのですが 通常のサイト運用では使っていない機能です。しかし「WP REST API」は有効になっていますので誰でもデータ取得できてしまうのはちょっとまずいなと思いますよね。

そこで「WP REST API」無効にする方法を紹介いたします。
 

Disable REST API プラグイン

WordPress4.7未満 と WordPress4.7以降では「WP REST API」の無効にする方法が変わりました。

Disable REST API — WordPress Plugins
https://ja.wordpress.org/plugins/disable-json-api/

WordPress4.7未満も、WordPress4.7も どちらも対応しています。
WordPress4.7での「WP REST API」を 無効にさせる部分を抜粋すると以下のコードになります。

/**
 * Returning an authentication error if a user who is not logged in tries to query the REST API
 * @param $access
 * @return WP_Error
 * Author: Dave McHale
 * Author URI: http://www.binarytemplar.com
 */
function DRA_only_allow_logged_in_rest_access( $access ) {
	if( ! is_user_logged_in() ) {
		return new WP_Error( 'rest_cannot_access', __( 'Only authenticated users can access the REST API.', 'disable-json-api' ), array( 'status' => rest_authorization_required_code() ) );
	}
	return $access;
}
add_filter( 'rest_authentication_errors', 'DRA_only_allow_logged_in_rest_access' );

「rest_authentication_errors」フックを使ってエラーコードを返す仕様です。

rest_authentication_errors | Hook | WordPress Developer Resources
https://developer.wordpress.org/reference/hooks/rest_authentication_errors/

この方法は調べると同様のやり方を説明しているサイトがいろいろ出てきます。
しかしこれだと embed も使えなくなります。
「embedもいらないよ」という場合はこのプラグインでOKです。

 



 

別のフックを使ってみる

embed は使えるように例外を追加したい場合は「rest_pre_dispatch」というフックを使ってみます。

rest_pre_dispatch | Hook | WordPress Developer Resources
https://developer.wordpress.org/reference/hooks/rest_pre_dispatch/

Description
Allow hijacking the request before dispatching by returning a non-empty. The returned value will be used to serve the request instead.

このフックの引数の情報を使って例外を設定する事ができそうです。
以下のコードを my-plugin.php に張り付けてください。

/*
 * REST APIを無効にする
 *
 * jetpack Embed以外
 *
 * License: GPLv2 or later
 */
function nendebcom_deny_restapi_except_embed( $result, $wp_rest_server, $request ){

	$namespaces = $request->get_route();

	// /oembed/1.0
	if( strpos( $namespaces, 'oembed/' ) === 1 ){
		return $result;
	}
	// /jetpack/v4
	if( strpos( $namespaces, 'jetpack/' ) === 1 ){
		return $result;
	}

	return new WP_Error( 'rest_disabled', __( 'The REST API on this site has been disabled.' ), array( 'status' => rest_authorization_required_code() ) );
}
add_filter( 'rest_pre_dispatch', 'nendebcom_deny_restapi_except_embed', 10, 3 );

 
namespaces で 例外にするかどうかを判別します。
現在のところ WordPress4.7ではこれだけあります。

/oembed/1.0
/oembed/1.0/embed

/wp/v2
/wp/v2/posts
/wp/v2/posts/(?P<id>[\d]+)
/wp/v2/posts/(?P<parent>[\d]+)/revisions
/wp/v2/posts/(?P<parent>[\d]+)/revisions/(?P<id>[\d]+)
/wp/v2/pages
/wp/v2/pages/(?P<id>[\d]+)
/wp/v2/pages/(?P<parent>[\d]+)/revisions
/wp/v2/pages/(?P<parent>[\d]+)/revisions/(?P<id>[\d]+)
/wp/v2/media
/wp/v2/media/(?P<id>[\d]+)
/wp/v2/types
/wp/v2/types/(?P<type>[\w-]+)
/wp/v2/statuses
/wp/v2/statuses/(?P<status>[\w-]+)
/wp/v2/taxonomies
/wp/v2/taxonomies/(?P<taxonomy>[\w-]+)
/wp/v2/categories
/wp/v2/categories/(?P<id>[\d]+)
/wp/v2/tags
/wp/v2/tags/(?P<id>[\d]+)
/wp/v2/users
/wp/v2/users/(?P<id>[\d]+)
/wp/v2/users/me
/wp/v2/comments
/wp/v2/comments/(?P<id>[\d]+)
/wp/v2/settings

さらに Jetpack を利用するとこれだけ追加されます。

/jetpack/v4
/jetpack/v4/connection
/jetpack/v4/connection/url
/jetpack/v4/connection/data
/jetpack/v4/connection/user
/jetpack/v4/site
/jetpack/v4/identity-crisis/confirm-safe-mode
/jetpack/v4/identity-crisis/start-fresh
/jetpack/v4/identity-crisis/migrate
/jetpack/v4/module/all
/jetpack/v4/module/all/active
/jetpack/v4/module/(?P<slug>[a-z\-]+)
/jetpack/v4/module/(?P<slug>[a-z\-]+)/active
/jetpack/v4/module/(?P<slug>[a-z\-]+)/data
/jetpack/v4/settings
/jetpack/v4/settings/(?P<slug>[a-z\-]+)
/jetpack/v4/options/(?P<options>[a-z\-]+)
/jetpack/v4/jumpstart
/jetpack/v4/updates/plugins
/jetpack/v4/notice/(?P<notice>[a-z\-_]+)
/jetpack/v4/plugins
/jetpack/v4/plugin/(?P<plugin>[a-z\/\.\-_]+)

この namespaces から jetpack と embed 以外はエラーを返す事で 無効にする事が出来るようにしました。

 
 

確認方法

以下のURL例でブラウザ( Firefox か choromeで )でテストしてみてください。
http:// ドメイン /wp-json/wp/v2/posts/?p=1
( 1 は記事の post ID です)

こんな表示になれば無効になっています。

{"code":"rest_disabled","message":"The REST API on this site has been disabled.","data":{"status":401}}

あとは embet と Jetpack(管理画面)が正常に動作してるかチェックしてみてください。

 
 

あとがき

今後「WP REST API」の仕組みを使ったプラグインが出てくると思われます。
その際、上記のコードのせいで 動作しなくなる場合が考えられます。
その場合は上記のコードを削除するか、使ってる namespaces を調べて 例外を追加してくださいね。