2026年10月3日
2026年10月3日
WordPress REST APIをトークンで認証する方法|アプリケーションパスワードとAPIキー
外部のシステムやスマートフォンアプリ、自動化のスクリプトから WordPress の REST API(/wp-json/ で始まる URL)にアクセスして投稿を作ったり、非公開の情報を読んだりするには、リクエストごとに「誰が送ったか」を証明する必要があります。WordPress には、そのための仕組みとしてアプリケーションパスワードが標準で入っています(WordPress 5.6 から)。この記事では、まずアプリケーションパスワードの使い方を説明し、次に自作のエンドポイントを API キーで守る方法を紹介します(2026年10月時点の WordPress 6.9 のソースで動作を確認しています)。
認証の方法の選び方
| 方法 | 向いている用途 | 必要なもの |
|---|---|---|
| Cookie と nonce | ログイン中の管理画面やテーマの JavaScript から呼ぶ | 標準(追加不要) |
| アプリケーションパスワード | 外部のプログラムが、特定のユーザーとして投稿・取得する | 標準(HTTPS のサイト) |
| 自作エンドポイント+API キー | 決まった相手からの通知(Webhook など)を受け取る | functions.php かプラグインにコードを書く |
| OAuth・JWT | 多数の外部アプリにユーザーごとの許可を出す | 別途プラグインが必要 |
外部のプログラムから WordPress の標準 API(投稿・固定ページ・メディアなど)を使うだけなら、まずアプリケーションパスワードを検討してください。プラグインを追加せずに使え、ユーザーごとに発行・取り消しができます。
方法1: アプリケーションパスワードを使う
使える条件
アプリケーションパスワードは、サイトが HTTPS で表示されている場合に使えます。HTTPS でないサイトでは、wp-config.php の環境の種類(WP_ENVIRONMENT_TYPE)が local のときだけ使えます。パスワードを HTTP のまま送ると途中で読まれるため、本番サイトでは HTTPS にしてから使います。
専用のユーザーを作る
アプリケーションパスワードで認証したリクエストは、そのパスワードを発行したユーザーの権限で動きます。管理者のアカウントで発行すると、外部のプログラムが管理者と同じことをできてしまいます。
連携の用途ごとに専用のユーザーを作り、必要な最小限の権限グループを割り当てます。
- 下書きを作るだけなら「寄稿者」
- 自分の記事を公開し、画像をアップロードするなら「投稿者」
- 他人の記事も編集するなら「編集者」
発行する
- 連携用のユーザーでログインし、管理画面の「ユーザー」→「プロフィール」を開きます(管理者が他のユーザーの分を発行する場合は、「ユーザー」の一覧から対象のユーザーを編集します)。
- 下のほうにある「アプリケーションパスワード」の欄に、用途が分かる名前(例:
blog-sync)を入力し、追加のボタンを押します。 - 4文字ずつ区切られた24文字のパスワードが表示されます。表示されるのはこのときだけなので、パスワード管理ツールなどに保存します。
curl で確かめる
ユーザー名とアプリケーションパスワードを、Basic 認証の形で送ります。パスワードの間の空白は、あってもなくても構いません(WordPress が英数字以外を取り除いてから照合します)。
# 認証できているかを確かめる(自分のユーザー情報が返れば成功)
curl -s https://example.com/wp-json/wp/v2/users/me \
-u 'api-user:abcd efgh ijkl mnop qrst uvwx'
# 下書きの投稿を作る
curl -s -X POST https://example.com/wp-json/wp/v2/posts \
-u 'api-user:abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
-d '{"title":"API test","content":"Hello","status":"draft"}'
認証できていないと、/wp/v2/users/me は 401 と rest_not_logged_in というエラーコードを返します。
アプリケーションパスワードが使えるのは、REST API と XML-RPC へのリクエストだけです。wp-login.php の画面からはログインできません。
取り消す・使えないようにする
プロフィール画面のアプリケーションパスワードの一覧には、最後に使われた日時が表示され、パスワードごとに取り消せます。漏れた疑いがあるとき、連携をやめたときは取り消してください。
サイト全体でアプリケーションパスワードを使わせたくない場合や、管理者だけに許可したい場合は、次のフィルターを使います。
<?php
// サイト全体で無効にする場合
// add_filter( 'wp_is_application_passwords_available', '__return_false' );
// 管理者(manage_options を持つユーザー)だけに許可する場合
add_filter( 'wp_is_application_passwords_available_for_user', 'mysite_app_passwords_for_admins', 10, 2 );
function mysite_app_passwords_for_admins( $available, $user ) {
return user_can( $user, 'manage_options' );
}
正しいパスワードでも 401 になるとき
Apache で PHP を CGI / FastCGI として動かしているサーバーでは、Authorization ヘッダーが PHP まで渡らず、認証情報が届かないことがあります。WordPress が書き出す .htaccess には、このヘッダーを渡すための次の行が含まれています。
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
.htaccess を手で書き換えて、この行が消えていないかを確認してください。管理画面の「ツール」→「サイトヘルス」には、Authorization ヘッダーが届いているかどうかの検査も含まれています。WAF やセキュリティプラグインが /wp-json/ へのアクセスを止めている場合も、認証に失敗したように見えます。
方法2: 自作のエンドポイントを API キーで守る
決まった外部サービスからの通知(Webhook)を受け取るなど、ユーザーとして振る舞う必要がない場合は、自作のエンドポイントを作り、事前に決めた API キーを確かめる方法があります。
API キーを作って wp-config.php に置く
推測されにくい長い文字列を作ります。
openssl rand -hex 32
出てきた文字列を、wp-config.php の「編集が必要なのはここまで」の行より上に定数として書きます。コードやデータベースに直接書かず、wp-config.php に置くことで、テーマやプラグインのファイルを共有しても漏れにくくなります。
define( 'MYSITE_API_KEY', 'ここに生成した文字列を書く' );
エンドポイントを登録する
register_rest_route() の permission_callback で API キーを確かめます。permission_callback は WordPress 5.5 から必須になっており、書かないと開発者向けの警告が出ます。誰でも呼べる公開のエンドポイントにする場合だけ __return_true を指定します。
<?php
/**
* POST /wp-json/mysite/v1/notify を、X-API-Key ヘッダーで認証する。
*/
add_action( 'rest_api_init', 'mysite_register_notify_route' );
function mysite_register_notify_route() {
register_rest_route(
'mysite/v1',
'/notify',
array(
'methods' => WP_REST_Server::CREATABLE, // POST
'callback' => 'mysite_handle_notify',
'permission_callback' => 'mysite_check_api_key',
)
);
}
function mysite_check_api_key( WP_REST_Request $request ) {
$sent = (string) $request->get_header( 'x-api-key' );
if ( ! defined( 'MYSITE_API_KEY' ) || '' === MYSITE_API_KEY || '' === $sent ) {
return new WP_Error( 'rest_forbidden', 'API key is required.', array( 'status' => 401 ) );
}
// 文字列の比較は、処理時間から推測されにくい hash_equals() を使う
if ( ! hash_equals( MYSITE_API_KEY, $sent ) ) {
return new WP_Error( 'rest_forbidden', 'Invalid API key.', array( 'status' => 403 ) );
}
return true;
}
function mysite_handle_notify( WP_REST_Request $request ) {
$params = $request->get_json_params();
$event = isset( $params['event'] ) ? sanitize_text_field( $params['event'] ) : '';
// ここで受け取った内容を保存・処理する
return rest_ensure_response(
array(
'received' => true,
'event' => $event,
)
);
}
呼び出す側は、API キーをヘッダーに入れて送ります。
curl -s -X POST https://example.com/wp-json/mysite/v1/notify \
-H 'X-API-Key: 生成したAPIキー' \
-H 'Content-Type: application/json' \
-d '{"event":"order.created"}'
キーが無いと 401、違うと 403 が返ります。
ユーザーの権限で守る場合
自作のエンドポイントを、アプリケーションパスワードで認証したユーザーに使わせたい場合は、API キーの代わりに権限を確かめます。
'permission_callback' => function () {
return current_user_can( 'edit_posts' );
},
安全に使うための注意
- API キーやパスワードを URL のクエリ文字列(
?key=...)に入れない。サーバーのアクセスログや閲覧履歴に残ります。ヘッダーで送ってください。 - 通信は HTTPS だけにする。Basic 認証のパスワードや API キーは、暗号化されていない通信では読めてしまいます。
- 連携先ごとに別のアプリケーションパスワード(または別のキー)を使い、不要になったら取り消す。
- 自作のエンドポイントでは、受け取った値を
sanitize_text_field()などで整えてから使う。 - 短時間に大量に呼ばれるおそれがある場合は、回数の制限も検討する。
まとめ
- 外部のプログラムから標準の REST API を使うなら、標準のアプリケーションパスワードを使う(HTTPS が前提)
- アプリケーションパスワードは発行したユーザーの権限で動くため、用途ごとに権限を絞った専用ユーザーを作る
- 自作のエンドポイントは
permission_callbackで守り、API キーは wp-config.php の定数に置いてhash_equals()で比べる - 正しい認証情報でも 401 になるときは、.htaccess の
HTTP_AUTHORIZATIONの行とサイトヘルスを確認する
関連記事: