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 にしてから使います。

専用のユーザーを作る

アプリケーションパスワードで認証したリクエストは、そのパスワードを発行したユーザーの権限で動きます。管理者のアカウントで発行すると、外部のプログラムが管理者と同じことをできてしまいます。

連携の用途ごとに専用のユーザーを作り、必要な最小限の権限グループを割り当てます。

  • 下書きを作るだけなら「寄稿者」
  • 自分の記事を公開し、画像をアップロードするなら「投稿者」
  • 他人の記事も編集するなら「編集者」

発行する

  1. 連携用のユーザーでログインし、管理画面の「ユーザー」→「プロフィール」を開きます(管理者が他のユーザーの分を発行する場合は、「ユーザー」の一覧から対象のユーザーを編集します)。
  2. 下のほうにある「アプリケーションパスワード」の欄に、用途が分かる名前(例: blog-sync)を入力し、追加のボタンを押します。
  3. 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 の行とサイトヘルスを確認する

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲