WordPress REST APIを特定のサイトにのみ許可する

WordPressのREST APIは標準で公開されておりサイトURLさえ知っていれば誰でも利用できます(セキュリティ系プラグインなどがRestAPIを無効化している場合は除く)。

なので、特定のURLからリクエストがあったときのみレスポンスを返すことにしました。

rest_pre_dispatch を使う

WordPressやphpは不得手なのですが、rest_pre_dispatchフックを使うことで既定のレスポンスを上書きできるようです。

よくある使われ方としては、「特定のプラグインのみREST APIを受け入れる」 が多いようです。

最近のプラグインやテーマはREST APIを利用しているものが多いですし、完全に無効化するのは難しいのでしょう。

add_filter('rest_pre_dispatch', 'restrict_rest_api_access'); 
function restrict_rest_api_access($result) {
    // 許可するURL
    $allowed_url = 'https://example.com';

    // リクエスト元のURLを取得
    $request_origin = $_SERVER['HTTP_ORIGIN'];

    // 許可するURL以外の場合、エラーレスポンスを返す
    if ($request_origin !== $allowed_url) {
        return new WP_Error('forbidden_rest_api', __('REST API access is forbidden from this origin.', 'text-domain'), array('status' => 403));
    }
    return $result;
}

$_SERVER[‘HTTP_ORIGIN’]でリクエスト元を取得し、一致・不一致で振り分けているシンプルなコードです。

これをfunction.php に追記すればOK。

もし複数のサイトにアクセス許可を出すのなら、下のようにします。

// 追加したfunction
function array_some(string $val , array $arr){
  return in_array( $val , $arr , true );
}

add_filter('rest_pre_dispatch', 'restrict_rest_api_access');

function restrict_rest_api_access($result) {
  // 許可するURLを配列に変更
  $urls = ['https://example.com', 'https://another.jp' ];

  $request_origin = $_SERVER['HTTP_ORIGIN'];

  // 追加したarray_some()で許可するURLかどうかチェック
  if ( !array_some($request_origin, $urls) ){
    return new WP_Error('forbidden_rest_api', __('REST API access is forbidden from this origin.', 'text-domain'), array('status' => 403));
  }
  return $result;
}
タイトルとURLをコピーしました