2026年6月2日

2026年6月2日

WordPress REST APIにJWT認証でアクセスする設定手順

WordPressのREST APIを外部のアプリやフロントエンドから認証付きで使うには、コアの「アプリケーションパスワード」を使う方法と、プラグインでJWT(JSON Web Token)認証を追加する方法があります。JWTはコアには含まれていないため、プラグインの導入、秘密鍵の設定、Authorizationヘッダーをサーバーに通す設定の3点が必要です。この記事では、JWTを選ぶべき場面の判断から、トークンの取得、APIの呼び出し、つまずきやすい点までを順に説明します。

JWTが必要かを先に判断する

WordPress 5.6以降には「アプリケーションパスワード」がコア機能として入っています。ユーザーのプロフィール画面でアプリごとのパスワードを発行し、HTTPSのBasic認証ヘッダーで送るだけでREST APIを認証付きで呼べます。プラグイン不要で、アプリ単位で失効もできるため、サーバー間連携やスクリプトからの更新ならこちらで足りることがほとんどです。

JWTが向いているのは、次のような場面です。

  • ユーザー本人がログインするアプリ: スマートフォンアプリやSPAで、ユーザーがIDとパスワードを入力し、その後は有効期限付きのトークンでAPIを呼びたい。
  • パスワードを保存したくない: 端末側にはパスワードではなく、期限切れになるトークンだけを持たせたい。
  • ヘッドレス構成で他のサービスとトークン方式を揃えたい。

逆に、「管理者が自分のサイトに外部ツールから投稿したい」程度なら、JWTを入れるより、アプリケーションパスワードの方が設定箇所が少なく安全に運用できます。

プラグインを選ぶ

JWT認証を追加する代表的なプラグインとして、公式ディレクトリの「JWT Authentication for WP REST API」があります。トークン発行用のエンドポイントを追加し、以後のリクエストで Authorization: Bearer ヘッダーのトークンを検証する仕組みです。同種のプラグインはほかにもありますが、認証まわりのプラグインは更新が止まると脆弱性がそのまま残るため、導入前に次の点を確認してください(2026年10月現在の状況は各プラグインのページで確かめる必要があります)。

  • 最終更新日が古すぎないか、利用中のWordPressのバージョンで検証済みか
  • サポートフォーラムで未解決の重大な不具合が放置されていないか
  • 有効期限の変更やトークン失効の手段が用意されているか

以下の手順は「JWT Authentication for WP REST API」を例にしています。別のプラグインでは定数名やエンドポイントが異なるため、各プラグインの説明に合わせて読み替えてください。

手順1: 秘密鍵とCORSの設定

トークンの署名に使う秘密鍵を wp-config.php に定義します。/* That's all, stop editing! */ の行より上に追記します。編集前に wp-config.php のバックアップを取っておきます。

define( 'JWT_AUTH_SECRET_KEY', 'your-long-random-secret-key' );
define( 'JWT_AUTH_CORS_ENABLE', true );

秘密鍵は推測できない十分に長いランダム文字列にします。たとえばサーバー上で openssl rand -base64 64 を実行すると生成できます。この値を知っている人は任意のユーザーのトークンを偽造できるため、Gitリポジトリや共有ドキュメントには載せないでください。

JWT_AUTH_CORS_ENABLE は、別ドメインのブラウザアプリから呼び出す場合にCORSヘッダーを付けるための設定です。サーバー間通信だけなら不要です。

手順2: Authorizationヘッダーをサーバーに通す

JWTでいちばんつまずきやすいのがここです。Apacheで PHP を CGI や FastCGI として動かしている環境では、Authorization ヘッダーがPHPに渡されず、プラグインからはトークンが送られていないように見えます。

Apacheの場合は、WordPressの .htaccess の RewriteEngine On の直後に次を追加します。

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

.htaccess の書き換えを誤るとサイト全体が500エラーになるため、元のファイルを保存してから編集し、保存後すぐにトップページが開くかを確認します。

Nginx と PHP-FPM の構成では、リクエストヘッダーは通常 HTTP_AUTHORIZATION としてPHPに渡されるため、追加設定が要らないことが多いです。ただし、前段にロードバランサーやCDNがある場合、そこでヘッダーが落とされていないかも確認対象になります。

手順3: トークンを取得する

プラグインを有効化すると、トークン発行用のエンドポイントが使えるようになります。ユーザー名とパスワードをPOSTすると、署名済みのトークンが返ります。

curl -X POST https://example.com/wp-json/jwt-auth/v1/token \
  -H "Content-Type: application/json" \
  -d '{"username":"api-user","password":"your-password"}'

成功すると、token を含むJSONが返ります。失敗した場合はエラーコードとメッセージが返るので、ユーザー名・パスワードの誤りか、設定不足かを切り分けられます。

このエンドポイントはパスワードを受け取る入り口なので、HTTPS以外では使わないこと、ログイン試行回数の制限やレート制限の対象に含めることが重要です。また、API専用のユーザーを作り、必要最小限のロール(投稿だけなら「投稿者」や「編集者」)を割り当てておくと、トークンが漏れたときの被害を抑えられます。

手順4: トークンでAPIを呼ぶ

取得したトークンを Authorization: Bearer ヘッダーに付けてリクエストします。まずは認証が通っているかを、ログイン中のユーザー情報を返すエンドポイントで確かめるのが手早い方法です。

TOKEN="取得したトークン"

# 認証確認: ログインユーザーとして扱われていれば自分の情報が返る
curl https://example.com/wp-json/wp/v2/users/me \
  -H "Authorization: Bearer $TOKEN"

# 下書き投稿を作成する例
curl -X POST https://example.com/wp-json/wp/v2/posts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title":"APIからの下書き","status":"draft"}'

/wp/v2/users/me が rest_not_logged_in などの未ログインを示すエラーを返す場合、トークンがWordPressに届いていません。手順2のヘッダー設定を見直します。トークン検証用のエンドポイント(/wp-json/jwt-auth/v1/token/validate)にPOSTして、トークン自体が有効かどうかを個別に確かめることもできます。

JavaScriptから呼ぶ場合も考え方は同じで、fetch のヘッダーに Authorization: Bearer を設定します。ブラウザに保存したトークンはXSSで盗まれる可能性があるため、保存場所と有効期限の短さはセットで考えてください。

有効期限と失効の考え方

JWTはサーバー側でセッションを持たないため、発行済みのトークンを1つだけ取り消すのは苦手です。このプラグインの既定の有効期限は長めに設定されているため、用途に合わせて短くしておくと安全です。有効期限はフィルターで変更できます。

// トークンの有効期限を発行から1時間にする
add_filter( 'jwt_auth_expire', function ( $expire, $issued_at ) {
	return $issued_at + HOUR_IN_SECONDS;
}, 10, 2 );

このコードはテーマの functions.php よりも、独自の小さなプラグインや mu-plugins に置く方が、テーマ変更の影響を受けません。

トークンが漏れた疑いがあるときは、JWT_AUTH_SECRET_KEY を新しい値に変えると、発行済みのトークンはすべて検証に失敗するようになります。全利用者が再ログインになる点は運用上の注意点です。

よくあるつまずき

  • トークンは取れるのにAPIが未ログイン扱いになる: ほとんどがAuthorizationヘッダーの欠落です。サーバー、CDN、セキュリティプラグインのどこでヘッダーが消えているかを順に確認します。
  • 設定不足のエラーが出る: JWT_AUTH_SECRET_KEY の定義漏れ、または wp-config.php の記述位置が下すぎて読み込まれていないことがあります。
  • REST APIそのものを無効化している: セキュリティプラグインでREST APIを未ログインユーザーに制限している場合、トークン発行エンドポイントまで止まることがあります。除外設定を確認します。
  • CORSエラー: ブラウザからの呼び出しでのみ起きます。サーバー間通信では無関係です。

まとめ

  • REST APIの認証はまずコアのアプリケーションパスワードで足りるかを検討し、ユーザー本人がログインするアプリなどでJWTを選びます。
  • JWTはプラグインで追加し、秘密鍵の定義、Authorizationヘッダーの受け渡し、HTTPSでの運用が前提です。
  • 動作確認は /wp/v2/users/me をトークン付きで呼ぶのが手早い方法です。
  • 有効期限は短めにし、漏えい時は秘密鍵の変更で一括失効させます。
  • 認証系のプラグインは保守状況を導入前と運用中の両方で確認してください。

お気軽にご相談ください

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