WordPress REST API にレート制限を実装する方法

ブログ

WordPress の REST API を公開する際、不正な利用や過剰なアクセスを防ぐためにレート制限を設けることが重要です。本記事では、API キーごとに 1 分間に 10 回、24 時間に 100 回までのリクエストを許可する方法を解説します。

基本的なAPIキーの認証については以下で解説しています。

実装方針

  • API キーごとにアクセス回数をカウント
  • transient を使用し、時間制限付きのカウンターを作成
  • 設定した制限を超えた場合、エラーレスポンスを返す

コードの実装

以下のコードを functions.php や適切なプラグインファイルに追加します。

API キーの認証とレート制限チェック

/**
 * APIキーの照合とレート制限を行うコールバック関数
 */
function movie_api_key_check(WP_REST_Request $request) {
    $api_key = $request->get_header('X-API-Key');

    if (empty($api_key)) {
        return new WP_Error('rest_forbidden', 'APIキーが必要です。', array('status' => 401));
    }

    // APIキーを持つユーザーを検索
    $args = array(
        'meta_key'    => 'api_key',
        'meta_value'  => $api_key,
        'number'      => 1,
        'count_total' => false,
    );
    $users = get_users($args);

    if (empty($users)) {
        return new WP_Error('rest_forbidden', '正しいAPIキーが必要です。', array('status' => 401));
    }

    // レート制限をチェック
    $limit_result = check_api_rate_limit($api_key);
    if (is_wp_error($limit_result)) {
        return $limit_result;
    }

    return true;
}

レート制限の実装

/**
 * APIのレート制限をチェック
 */
function check_api_rate_limit($api_key) {
    $minute_limit = 10;  // 1分間に10回
    $daily_limit = 100;   // 24時間に100回

    $minute_key = "api_rate_{$api_key}_minute";
    $daily_key = "api_rate_{$api_key}_daily";

    $minute_count = get_transient($minute_key) ?: 0;
    $daily_count = get_transient($daily_key) ?: 0;

    if ($minute_count >= $minute_limit) {
        return new WP_Error('rest_forbidden', '1分間のAPIリクエスト制限を超えました。', array('status' => 429));
    }

    if ($daily_count >= $daily_limit) {
        return new WP_Error('rest_forbidden', '24時間のAPIリクエスト制限を超えました。', array('status' => 429));
    }

    // カウントを更新
    set_transient($minute_key, $minute_count + 1, 60);       // 60秒有効
    set_transient($daily_key, $daily_count + 1, 24 * 60 * 60); // 24時間有効

    return true;
}

API エンドポイントの登録

// GETリクエスト用のエンドポイントを登録
function register_movie_data_get_endpoint() {
    register_rest_route('movie/v1', '/get/', array(
        'methods'             => 'GET',
        'callback'            => 'get_movie_data',
        'permission_callback' => 'movie_api_key_check',
    ));
}
add_action('rest_api_init', 'register_movie_data_get_endpoint');

仕組みの解説

  1. API キーの認証
    – リクエストヘッダー X-API-Key を取得し、ユーザーの api_key と照合
    – 一致しない場合、401 Unauthorized エラーを返す

  2. レート制限の適用
    transient を使用して、API キーごとにリクエスト数を管理
    – 1 分間 (minute_limit) と 24 時間 (daily_limit) のリクエスト数をカウント
    – 制限を超えた場合、429 Too Many Requests エラーを返す

  3. API の登録
    register_rest_route でエンドポイント /movie/v1/get/ を作成
    movie_api_key_check による認証・レート制限チェックを実施

まとめ

この方法を使えば、WordPress REST API に簡単にレート制限を実装できます。transient を利用することで、データベースへの負荷を抑えつつ、柔軟な制限を設けることが可能です。

以下記事では管理者ユーザーには制限をかけない方法を紹介しています。

タイトルとURLをコピーしました