permission_callback がない警告の対処|REST ルートの権限設計

結論

「REST API ルート定義 ◯◯ に必須の引数 permission_callback がありません」という通知は、register_rest_route() の引数に permission_callback が無いときに出ます。対処は、そのルートの性格に合わせて値を決めるだけです。

ルートの性格 permission_callback
誰でも読んでよい公開データ '__return_true'
ログイン中の編集者以上だけ function () { return current_user_can( 'edit_posts' ); }
特定の投稿を編集できる人だけ current_user_can( 'edit_post', $request['id'] )
管理者だけ current_user_can( 'manage_options' )

「通知を消す」目的で、書き込み系にまで __return_true を付けるのは避けてください。通知は消えますが、誰でも書き込める API になります。

原因・仕組み

公式リファレンスによると、permission_callback は WordPress 5.5.0 から必須になりました。省略すると、デバッグ時に「公開ルートなら __return_true を使ってください」という趣旨の通知が出ます。必須化の狙いは、権限の考慮が漏れたまま公開される API を減らすことにあると考えられます。

通知の実体は _doing_it_wrong() です。そのため、WP_DEBUG が有効なときにログや画面に出ます。無効な本番環境では出ませんが、通知が出ないだけで、設計の問題は残ります。

手順(サンプルコード)

悪い例(権限の意図が不明。コピーしないでください)と、良い例を並べます。

// 悪い例: permission_callback がない
register_rest_route( 'ks/v1', '/bad', array(
    'methods'  => 'GET',
    'callback' => 'ks_bad_callback',
) );

// 良い例1: 公開データ
register_rest_route( 'ks/v1', '/public', array(
    'methods'             => 'GET',
    'callback'            => 'ks_public_callback',
    'permission_callback' => '__return_true',
) );

// 良い例2: 書き込みは権限を確認
register_rest_route( 'ks/v1', '/save', array(
    'methods'             => 'POST',
    'callback'            => 'ks_save_callback',
    'permission_callback' => function () {
        return current_user_can( 'edit_posts' );
    },
) );

これらは rest_api_init の中で呼びます(全体の手順はREST API カスタムエンドポイントの作り方)。

動作確認(検証環境と結果)

WordPress 7.1.2、PHP 8.2.12 で、doing_it_wrong_run をフックして通知の内容を取得しました(php C:Tempwp-testrun.php rest-permission-callback-missing-notice.php)。

  • permission_callback の無いルートと、__return_true を付けたルートを登録し、rest_get_server() で rest_api_init を発火。
  • 通知は1件のみ。対象は register_rest_route、バージョンは 5.5.0、メッセージは ks/v1/bad に必須の引数 permission_callback が無い、という内容でした(日本語環境)。__return_true を付けたルートには通知が出ませんでした。
  • 通知が出たルート /ks/v1/bad に、rest_do_request() で GET したところ、ステータスは 200 で、処理は実行されました。つまり、通知は警告であり、アクセスは拒否されません。

認証付きの本番相当の環境や、HTTP 越しのリクエストでの検証は行っていません。

permission_callback がない警告の対処の注意点

  • 通知は WP_DEBUG が有効なときに目に付きます。本番で見えなくても、対処は必要です。
  • permission_callback が false を返すと拒否されます。本検証では、未ログインの場合に 401 の rest_forbidden が返りました。別の理由で拒否したい場合は WP_Error を返してください。
  • Cookie 認証で書き込みをするときは、リクエストに X-WP-Nonce(wp_rest の nonce)が必要です。無いと、ログインしていても未認証と扱われます。
  • permission_callback は「アクセスしてよいか」の判定です。引数の検証は args の validate_callback で分けて書きます。
  • ルートを複数のメソッドで登録する場合は、メソッドごとに permission_callback を書きます。

permission_callback がない警告の対処でよくあるミス

  • 通知を消す目的だけで、書き込みルートに '__return_true' を指定する。
  • current_user_can( 'manage_options' ) を、関数ではなく結果の真偽値(呼び出し済み)として渡してしまう。コールバックとして渡す必要があります。
  • テーマの functions.php 内で、サードパーティ製ライブラリのルート登録に通知が出て、自分のコードの問題と勘違いする。通知のルート名で、発生元を判断します。
  • 公開ルートなのに、本来は非公開の投稿やユーザー情報まで返してしまう。権限が不要でも、返すデータの範囲は別に設計します。

permission_callback がない警告の対処のチェックリスト

  • すべてのルートに permission_callback があるか。
  • 書き込み系で __return_true になっていないか。
  • 返すデータに、非公開の情報が含まれていないか。
  • 認証付きのリクエストに nonce またはアプリケーションパスワードを使っているか。
  • 通知のルート名から、自分のコードか他のプラグインかを確認したか。

permission_callback がない警告の対処のFAQ(よくある質問)

Q. 5.5.0 より前のコードでも、通知を消すだけでよいですか。
A. 公開してよいルートなら '__return_true' で構いません。ただし、書き込み系は権限確認を新たに設計してください。

Q. 通知が出るプラグインのルートを、自分で直せますか。
A. プラグインのファイルを直接編集せず、作者へ報告するか、更新を待つのが安全です。

Q. permission_callback の中で、$request の値を使えますか。
A. 使えます。コールバックの第1引数が WP_REST_Request です。

筆者の見解(permission_callback がない警告の対処)

この必須化は、公開と非公開を最初に意識させる、よい変更だと考えます。通知が出たら、まず「このルートは誰が使うのか」を言葉にしてください。それが決まれば、コールバックは1行で書けることがほとんどです。迷う場合は、公開しない方向(権限必須)から始め、必要になってから緩めるほうが、安全側に倒せると思います。

permission_callback がない警告の対処の関連項目

出典(一次情報)

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