WordPress関数一覧まとめ【Part3】Ajax・REST API・セキュリティ設計ガイド|nonce検証からWP_Filesystem・SSRF対策まで

WordPress関数一覧まとめ【Part3】Ajax・REST API・セキュリティ設計ガイド|nonce検証からWP_Filesystem・SSRF対策まで WordPress
この記事は約44分で読めます。
  1. admin-ajax と REST API の使い分け
    1. admin-ajax.php を選ぶケース
    2. REST API を選ぶケース
    3. 共通して守るべきこと
  2. Ajax(admin-ajax.php)の実装パターン
    1. wp_ajax_{action}|ログインユーザー向け
    2. wp_ajax_nopriv_{action}|未ログインユーザーも含む
    3. check_ajax_referer()|CSRF対策
    4. wp_send_json_success() / wp_send_json_error()|統一レスポンス
    5. wp_localize_script()|JavaScriptへPHPの値を渡す
  3. REST API の実装パターン(register_rest_route)
    1. register_rest_route()|エンドポイントの登録
    2. permission_callback|アクセス権限の制御(最重要)
    3. 返り値|配列・WP_REST_Response・WP_Error
    4. URLパラメータとルートパターン
  4. セキュリティの「型」|nonce・権限・サニタイズ
    1. サニタイズ関数一覧
    2. wp_create_nonce() / wp_verify_nonce()|トークン生成と検証
    3. REST APIでのnonce
  5. 外部API通信|HTTP API(wp_remote_*)
    1. wp_remote_get() / wp_remote_post()
    2. 外部APIを扱う際の心構え
  6. キャッシュ|Transients API
    1. set_transient() / get_transient() / delete_transient()
    2. キャッシュキー戦略
  7. Cron|重い処理の非同期化
    1. wp_schedule_event() / wp_clear_scheduled_hook()
    2. wp_schedule_single_event()|1回だけ実行
    3. WP-Cronの制限と対策
  8. デバッグとログ|非同期処理のトラブルシューティング
    1. WP_DEBUG / WP_DEBUG_LOG
    2. error_log()|デバッグ情報の出力
    3. デバッグのチェックポイント
  9. 拡張性設計|自前フック(apply_filters / do_action)
    1. do_action()|処理の拡張ポイントを作る
    2. apply_filters()|値の変更を許可する
    3. フック命名規則
  10. コンテキスト検出|wp_doing_ajax / wp_doing_cron / wp_get_environment_type
    1. wp_doing_ajax()|Ajaxリクエストかどうかを判定
    2. wp_doing_cron()|Cronリクエストかどうかを判定
    3. wp_get_environment_type()|実行環境を検出
  11. REST APIヘルパー関数|rest_url / rest_ensure_response
    1. rest_url()|REST APIエンドポイントのURLを安全に生成
    2. rest_ensure_response()|レスポンスを正規化
  12. HTTP通信の完全版|PUT/DELETE対応とSSRF対策
    1. wp_remote_request()|任意のHTTPメソッドでリクエスト
    2. wp_safe_remote_get() / wp_safe_remote_post()|SSRF対策
    3. wp_remote_retrieve_headers()|レスポンスヘッダーの取得
  13. ユーティリティ関数|wp_json_encode / wp_parse_args / wp_unslash
    1. wp_json_encode()|日本語対応の安全なJSON出力
    2. wp_parse_args()|引数のデフォルト値マージ
    3. wp_unslash()|マジッククォートの除去
  14. セキュリティユーティリティ|トークン生成・ハッシュ・ファイル操作
    1. wp_generate_password()|暗号学的に安全なランダム文字列
    2. wp_hash()|HMACハッシュ
    3. wp_upload_dir()|アップロードディレクトリの情報を取得
    4. WP_Filesystem|安全なファイル読み書き
    5. sanitize_file_name()|アップロードファイル名の無害化
    6. wp_json_file_decode()|JSONファイルの安全な読み込み
  15. まとめ:壊れない非同期機能の共通パターン

この記事の結論

WordPressの非同期通信はadmin-ajax.php(既存互換・小規模向け)とREST API(設計重視・拡張向け)の2方式があり、どちらを選んでも守るべきセキュリティ対策は同じです。「権限チェック → nonce検証 → サニタイズ → バリデーション → エスケープ」の5段階を型として身につけ、外部API通信にはTransientsキャッシュ、重い処理にはWP-Cronを組み合わせてください。

検証環境:WordPress 6.9 / Xserver / PHP 8.5.2(2026年3月時点)

モダンなWordPressプラグインでは、非同期通信(Ajax/REST API)が欠かせません。「いいね」ボタン、無限スクロール、管理画面での非同期保存、外部サービスとの連携——ユーザー体験を向上させる多くの機能が非同期通信で実現されています。

しかし、非同期機能が増えるほどセキュリティ設計がボトルネックになります。外部からリクエストを受け付ける機能は、攻撃者にとって格好のターゲットだからです。

この記事では、admin-ajax.php方式とREST API方式の両方について、「どちらを選ぶべきか」から「安全に実装するパターン」まで、関数ベースで解説します。

この記事はWordPress関数解説シリーズのPart3(Ajax・REST API・セキュリティ編)です。テーマ制作で使う関数はPart1、プラグインの設定画面・メニュー・CPTはPart2で解説しています。

admin-ajax と REST API の使い分け

迷ったら「既存機能の保守ならadmin-ajax、新規開発ならREST API」で判断してください。どちらを選んでもセキュリティ対策(nonce・権限・サニタイズ)は同じで、違いは入口(エンドポイント)の設計だけです。

admin-ajax vs REST API 処理フロー比較

WordPressで非同期通信を実装する方法は、大きく分けて2つあります。

admin-ajax.php を選ぶケース

古くからの定番で実装がシンプルです。ログイン必須の管理系機能、既存プラグインやテーマとの互換性維持、小規模な機能でRESTの設計までは不要な場合に向いています。

REST API を選ぶケース

設計が明確でエンドポイントの構造が綺麗になります。フロントエンド(React、Vue等)との連携、外部アプリケーションとの連携、ブロックエディタ(Gutenberg)との統合、将来的な拡張性を重視する場合に選択します。

共通して守るべきこと

どちらの方式でも、セキュリティ対策は同じです。nonce検証(CSRF対策)、権限チェック、入力値のサニタイズ、出力時のエスケープ——この4つは方式に関係なく必須です。

Ajax(admin-ajax.php)の実装パターン

admin-ajax.phpは、wp_ajax_{action}でログインユーザー向け、wp_ajax_nopriv_{action}で未ログインユーザー向けのエンドポイントを登録します。必ずcheck_ajax_referer()でnonce検証し、wp_send_json_success()/wp_send_json_error()で統一されたレスポンスを返してください。

admin-ajax.phpは、WordPressに最初から用意されているAjax処理の仕組みです。フォームデータを/wp-admin/admin-ajax.phpにPOSTすることで、PHPの処理を非同期に呼び出せます。

wp_ajax_{action}|ログインユーザー向け

このアクションフックは、ログイン済みユーザーからのリクエストのみを処理します。管理画面での設定保存、ユーザー固有のデータ操作など、認証が必要な機能に使用します。

wp_ajax_nopriv_{action}|未ログインユーザーも含む

noprivは「no privileges(権限なし)」の略で、未ログインユーザーからのリクエストも受け付けるエンドポイントです。公開フォームの送信処理、投票機能、問い合わせフォームなどに使用します。このエンドポイントは「公開API」に近い存在であり、入力チェック、レート制限、スパム対策がより重要になります。

check_ajax_referer()|CSRF対策

CSRF(クロスサイトリクエストフォージェリ)攻撃を防ぐ関数です。第1引数はnonce生成時のアクション名、第2引数はリクエストパラメータ名です。検証に失敗するとデフォルトでwp_die()が実行されます。第3引数にfalseを渡すと、戻り値で判定できます。

wp_send_json_success() / wp_send_json_error()|統一レスポンス

適切なHTTPヘッダーを設定し、JSON形式のレスポンスを出力してスクリプトの実行を終了します。手動でjson_encode()header()を書く必要がなく、統一されたレスポンス形式を提供できます。

wp_localize_script()|JavaScriptへPHPの値を渡す

JavaScript側でAjaxリクエストを送信するには、admin-ajax.phpのURLとnonceが必要です。これらの値はPHP側でしか生成できないため、wp_localize_script()でJavaScriptのグローバル変数として渡します。

REST API の実装パターン(register_rest_route)

REST APIではregister_rest_route()でエンドポイントを登録し、permission_callbackで権限チェックを必ず設定します。省略するとデバッグモードで警告が出るだけでなく、セキュリティホールの原因になります。

WordPress REST APIは、WordPress 4.7から標準搭載された機能です。/wp-json/以下にエンドポイントを定義し、HTTPメソッド(GET、POST、PUT、DELETE等)に応じた処理を行います。

register_rest_route()|エンドポイントの登録

第1引数の名前空間はプラグイン識別子とバージョンを組み合わせます(例:myplugin/v1)。第2引数がパス、第3引数でメソッド・コールバック・権限チェック等を指定します。

permission_callback|アクセス権限の制御(最重要)

permission_callbackは、REST APIのセキュリティにおいて最も重要な設定です。このコールバックがtrueを返した場合のみ、メインのコールバックが実行されます。

返り値|配列・WP_REST_Response・WP_Error

コールバック関数からは、配列(自動的にJSONに変換)、WP_REST_Response(HTTPステータスやヘッダーを制御)、WP_Error(エラーを返す)のいずれかを返します。

URLパラメータとルートパターン

URLパスの一部をパラメータとして取得でき、リソースIDをURLに含めたRESTfulな設計が可能です。

セキュリティの「型」|nonce・権限・サニタイズ

非同期処理のセキュリティは「権限チェック → nonce検証 → サニタイズ → バリデーション → エスケープ」の5段階を毎回この順序で実行することが「型」です。1つでも欠けるとセキュリティホールになります。

非同期処理セキュリティの5段階チェックフロー

非同期機能は「外部から叩かれる」機能です。だからこそ入口の守りがすべてです。

サニタイズ関数一覧

関数 用途 動作
sanitize_text_field() 1行テキスト HTMLタグ・改行を除去
sanitize_textarea_field() 複数行テキスト HTMLタグ除去・改行保持
sanitize_email() メールアドレス メール形式に整形
absint() 正の整数 絶対値の整数に変換
sanitize_key() キー名 英小文字・数字・_・-のみ

wp_create_nonce() / wp_verify_nonce()|トークン生成と検証

nonceは「Number used ONCE」の略ですが、WordPressでは一定時間有効なトークンです。CSRF攻撃を防ぐために使用します。

REST APIでのnonce

REST APIでも操作系エンドポイントではnonceの使用が推奨されます。WordPressのREST APIはX-WP-Nonceヘッダーまたは_wpnonceパラメータでnonceを受け付けます。

外部API通信|HTTP API(wp_remote_*)

外部APIとの通信にはPHPのcURLではなくWordPressのHTTP API(wp_remote_get/wp_remote_post)を使ってください。プロキシ設定やSSL証明書の処理が自動化され、is_wp_error()でエラーハンドリングも統一できます。

外部サービスのAPIと連携する場合、PHPのfile_get_contents()cURLを直接使うのではなく、WordPressのHTTP APIを使用します。WordPress環境に最適化されており、環境差異を吸収してくれます。

wp_remote_get() / wp_remote_post()

外部APIを扱う際の心構え

外部APIは「遅い・落ちる・仕様が変わる」ものです。タイムアウト設定(デフォルト5秒では短い場合がある)、エラーハンドリング(4xx、5xx、タイムアウトそれぞれへの対応)、Transientsによるキャッシュ、一時的なエラーへのリトライロジック——これらを前提に設計してください。

キャッシュ|Transients API

毎回外部APIを叩く、毎回重い集計クエリを実行する——これをやめるだけでサイトのレスポンスは劇的に改善します。set_transient()で有効期限付きキャッシュを保存し、キャッシュキーにはバージョン番号を含めることで一括無効化もできます。

Transients APIキャッシュフロー

Transients APIは、データベースのwp_optionsテーブルに保存される有効期限付きキャッシュです。Object Cache(Redis、Memcached等)が有効な環境では自動的にそちらを使用し、さらに高速になります。

set_transient() / get_transient() / delete_transient()

WordPressには有効期限を指定するための定数が用意されています。MINUTE_IN_SECONDS(60)、HOUR_IN_SECONDS(3600)、DAY_IN_SECONDS(86400)、WEEK_IN_SECONDS(604800)です。

キャッシュキー戦略

キャッシュで最も多い事故は「キーが雑で、異なる条件のデータが混在する」ことです。プラグイン名、バージョン(仕様変更時に一括無効化するため)、スコープ(マルチサイトならblog_id)、条件(検索語、ページ番号等)をキーに含めます。

Cron|重い処理の非同期化

レスポンスタイムに影響する重い処理は、ユーザーのリクエスト中に実行するのではなくWP-Cronでバックグラウンド処理にしてください。プラグイン有効化時にwp_schedule_event()で登録し、無効化時にwp_clear_scheduled_hook()で必ず解除します。

wp_schedule_event() / wp_clear_scheduled_hook()

wp_schedule_single_event()|1回だけ実行

即座には実行せず、指定時刻に1回だけ実行したいタスクに使用します。データインポート完了後のメール通知などに適しています。

WP-Cronの制限と対策

WP-Cronは「擬似Cron」であり、WordPressへのアクセスがあったときに初めてチェックが実行されます。アクセスが少ないサイトではスケジュール通りに実行されないことがあります。高い精度が必要な場合は、サーバーのcronで直接wp-cron.phpを叩く設定を検討してください。

この場合、wp-config.phpでWP-Cronの自動実行を無効化します。

WP-Cronが動かない問題の詳しい対処法は「WP-Cronが動かない|Xserverのcronで時間通りのメール送信を取り戻した話」で、Xserverでの具体的な設定手順を解説しています。

デバッグとログ|非同期処理のトラブルシューティング

非同期処理のバグは「通信が失敗しているのか」「権限で弾かれているのか」「nonceが期限切れなのか」の切り分けが9割です。ブラウザのNetworkタブでHTTPステータスを確認し、PHPのdebug.logでサーバー側のエラーを確認してください。

WP_DEBUG / WP_DEBUG_LOG

wp-config.phpで以下を設定すると、エラーがログファイルに記録されます。

error_log()|デバッグ情報の出力

デバッグのチェックポイント

非同期処理がうまく動かないとき、以下の順序でチェックすると効率的です。リクエストはブラウザのNetworkタブで届いているか確認。HTTPステータスが403なら権限、400ならバリデーション、500ならPHPエラー。nonceは生成時刻とアクション名の一致を確認。権限はログイン状態とcapabilityを確認。PHPエラーはdebug.logを確認します。

拡張性設計|自前フック(apply_filters / do_action)

プラグインを「他の開発者が拡張できる設計」にするにはapply_filters()とdo_action()で独自フックを提供します。Part2で解説したadd_action/add_filterは既存フックに処理を追加する側でしたが、ここでは「フックを作る側」の設計を解説します。

do_action / apply_filters のフロー

プラグイン審査でも「適切なフックの提供」は品質シグナルとして評価されます。自分のプラグインのデータや動作を、テーマや他のプラグインがカスタマイズできるようにしておくことが、長期運用されるプラグインの条件です。

do_action()|処理の拡張ポイントを作る

「ここで何か追加の処理を実行したい人がいるかもしれない」というポイントに設置します。たとえばデータ保存後やメール送信前などです。

apply_filters()|値の変更を許可する

「この値をカスタマイズしたい人がいるかもしれない」というデータに設置します。デフォルト値を渡し、フィルターを通して最終値を決定します。

フック命名規則

フック名には必ずプラグインのプレフィックスを付けてください。他プラグインとの名前衝突を防ぐためです。命名パターンは{prefix}_{対象}_{タイミング}が一般的です。例:myplugin_order_before_savemyplugin_api_response_filtered

コンテキスト検出|wp_doing_ajax / wp_doing_cron / wp_get_environment_type

「今のリクエストがAjaxなのかCronなのか通常ページなのか」を正確に判定することで、不要な処理のスキップやデバッグの切り分けが容易になります。wp_get_environment_type()でステージング環境を検出すれば、本番では無効にすべきデバッグ処理を安全に制御できます。

wp_doing_ajax()|Ajaxリクエストかどうかを判定

WordPress 4.7で追加された関数で、defined( 'DOING_AJAX' ) && DOING_AJAXを短く書けるラッパーです。admin-ajax.php経由のリクエスト時にtrueを返します。REST APIリクエストではfalseを返す点に注意してください。

wp_doing_cron()|Cronリクエストかどうかを判定

WP-Cronで実行されているリクエストかどうかを判定します。Cron実行中に不要な処理(アセットの読み込みなど)をスキップする場合に使います。

wp_get_environment_type()|実行環境を検出

WordPress 5.5で追加された関数で、wp-config.phpWP_ENVIRONMENT_TYPE定数を読み取り、localdevelopmentstagingproductionのいずれかを返します。未設定の場合はproductionがデフォルトです。

REST APIヘルパー関数|rest_url / rest_ensure_response

REST APIのURL生成にはrest_url()を使い、コールバックの返り値にはrest_ensure_response()を通すことで、エンドポイントの設計品質が上がります。URLのハードコードやレスポンス形式の不統一を防ぐ関数です。

rest_url()|REST APIエンドポイントのURLを安全に生成

JavaScriptに渡すAPIのベースURLを安全に生成します。/wp-json/のパスをハードコードすると、パーマリンク設定が「基本」の場合に?rest_route=/形式になることを見落として壊れます。

rest_ensure_response()|レスポンスを正規化

コールバック関数が配列、WP_REST_Response、WP_Errorのいずれを返しても、適切なWP_REST_Responseオブジェクトに変換します。コールバックの最後にこの関数を通しておくと、返り値の型を意識しなくて済みます。

HTTP通信の完全版|PUT/DELETE対応とSSRF対策

外部APIとのCRUD操作にはwp_remote_request()でPUT/DELETE/PATCHメソッドを使います。また、ユーザー入力のURLを外部リクエストに使う場合はwp_safe_remote_get()でSSRF攻撃(内部ネットワークへの不正アクセス)を防いでください。

wp_remote_get vs wp_safe_remote_get

wp_remote_request()|任意のHTTPメソッドでリクエスト

Section4で解説したwp_remote_get()wp_remote_post()はGET/POST専用ですが、RESTful APIとの通信ではPUT・DELETE・PATCHも必要です。wp_remote_request()で任意のメソッドを指定できます。

wp_safe_remote_get() / wp_safe_remote_post()|SSRF対策

通常のwp_remote_get()はURLの検証を行いません。ユーザーが入力したURLをそのまま渡すと、http://localhost/http://192.168.1.1/のような内部ネットワークへのリクエストが実行される危険があります(SSRF攻撃)。wp_safe_remote_get()はプライベートIPやループバックアドレスへのリクエストをブロックします。

wp_remote_retrieve_headers()|レスポンスヘッダーの取得

APIのレート制限情報やページネーション情報はレスポンスヘッダーに含まれることが多いです。

ユーティリティ関数|wp_json_encode / wp_parse_args / wp_unslash

非同期処理で頻繁に使うユーティリティ関数を3つ紹介します。wp_json_encode()はjson_encode()より安全な日本語対応のJSON出力、wp_parse_args()は関数の引数をデフォルト値とマージする定番パターン、wp_unslash()はPHPのマジッククォートを除去する前処理です。

wp_json_encode()|日本語対応の安全なJSON出力

PHPのjson_encode()はデフォルトで日本語をUnicodeエスケープ(\u3042形式)します。wp_json_encode()JSON_UNESCAPED_UNICODEフラグを自動的に適用し、エンコードエラー時にもfalseではなく空文字列を返すため安全です。

wp_parse_args()|引数のデフォルト値マージ

関数に渡されたユーザー引数とデフォルト値を安全にマージする関数です。shortcode_atts()がショートコード専用なのに対し、wp_parse_args()は汎用的に使えます。配列・オブジェクト・クエリ文字列のいずれの形式でも受け取れます。

wp_unslash()|マジッククォートの除去

WordPressは$_GET$_POST$_COOKIE$_SERVERの値にスラッシュを自動追加します(wp_magic_quotes()による処理)。サニタイズ前にwp_unslash()で余分なスラッシュを除去しないと、「O\’Reilly」のようなデータがデータベースに入ります。

セキュリティユーティリティ|トークン生成・ハッシュ・ファイル操作

APIトークンの生成にはwp_generate_password()、データの完全性検証にはwp_hash()、ファイル操作にはWP_Filesystemを使ってください。PHPのrand()やfile_put_contents()を直接使うと、セキュリティ上の問題が生じます。

wp_generate_password()|暗号学的に安全なランダム文字列

APIトークン、セッションID、ワンタイムキーなど、推測不可能な文字列が必要な場面で使います。PHPのrand()uniqid()は暗号学的に安全ではありませんが、この関数はrandom_bytes()ベースの安全な乱数を生成します。

wp_hash()|HMACハッシュ

データの完全性を検証するためのHMACハッシュを生成します。WordPress固有のソルト(wp-config.phpAUTH_SALT)を使用するため、同じ入力でもサイトごとに異なるハッシュが生成されます。

wp_upload_dir()|アップロードディレクトリの情報を取得

プラグインが一時ファイルやログを保存する場所を取得する際に使います。wp-content/uploads/のパスをハードコードすると、UPLOADS定数やフィルターでカスタマイズされている環境で壊れます。

WP_Filesystem|安全なファイル読み書き

プラグイン審査ではfile_put_contents()file_get_contents()の直接使用は指摘対象です。WP_Filesystemを使うことで、FTP/SSH経由のファイル操作にも対応した安全なファイル操作が実現します。

sanitize_file_name()|アップロードファイル名の無害化

ユーザーがアップロードしたファイル名には、ディレクトリトラバーサル攻撃のための../や、特殊文字が含まれる可能性があります。sanitize_file_name()は危険な文字を除去し、安全なファイル名に変換します。

wp_json_file_decode()|JSONファイルの安全な読み込み

WordPress 5.9で追加された関数で、JSONファイルを読み込んでデコードします。file_get_contents() + json_decode()の組み合わせを1関数で安全に行えます。設定ファイルやデータファイルの読み込みに使います。

まとめ:壊れない非同期機能の共通パターン

Ajax/REST APIを使った「壊れにくい」機能には共通パターンがあります。入口の守り(権限・nonce・サニタイズの3点セット)、統一されたレスポンス形式、Transientsによるキャッシュ、外部APIを信頼しない設計、問題追跡のためのログ出力——この5つを守れば、安全で保守しやすい非同期機能が作れます。

原則 要点
入口の守りが固い 権限チェック・nonce検証・サニタイズの3点セットが常に存在する
レスポンス形式が統一 成功も失敗も一貫したJSON構造とHTTPステータスで返す
重い処理を直接叩かない Transientsでキャッシュ、WP-Cronでバックグラウンド処理
外部APIを信頼しない タイムアウト・エラーハンドリング・フォールバックを必ず実装
ログが残る 問題発生時に原因を追跡できるerror_log()が仕込まれている

重要なのは、これらの関数を暗記することではありません。「どんな場面で」「何を守りながら」「どう組み合わせるか」というパターンを身につけることです。

なお、プラグイン開発で使うセキュリティ関数(エスケープ・サニタイズ)の基本はPart1で、Settings API・メニュー・CPTはPart2で解説しています。

プラグイン審査では、ここで解説したnonce検証やサニタイズの実装が審査項目に含まれています。審査の全手順と差し戻し対応については「WordPress.orgのプラグイン審査に一発で通すための全手順」を参照してください。

WordPress
この記事を書いた人
rapls

Web開発歴6年超のフリーランスエンジニア。WordPress.orgにプラグインを2本公開中。「自分が3時間ハマった問題を、誰かが3分で解決できるように」がブログの原点。Xserver環境でのトラブルシューティングとAI駆動開発が得意分野です。

raplsをフォローする
raplsをフォローする

コメント

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