問題点:プライベートルートでの認証エラー
ヘッドリスWordPressサイトやモバイルアプリの構築は、単純なGETリクエストの段階ではスムーズに進むことが多いものです。公開記事の取得などは問題なく動作します。しかし、ユーザー情報を更新したり下書きを作成しようとしたりした途端、壁にぶつかります。有効な認証情報を使用しているにもかかわらず、サーバーがリクエストを拒否し、rest_forbiddenエラーが発生します。
{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":401}}
このエラーは通常、WordPressがあなたの身元を認識できていないか、必要な権限を持っていないと判断していることを意味します。これは管理者アカウントでも発生します。多くの場合、原因はWordPressに届く前に認証情報を削除してしまうサーバー設定にあります。
デバッグプロセス:ボトルネックの特定
通信のどこで問題が発生しているかを確認する前に、アプリケーションコードを変更し始めないでください。問題を切り分けるために、以下の手順に従ってください。
- ステータスコードの分析: 401ステータスは「本人確認」の問題です。サーバーはあなたが誰であるかを知りません。403ステータスは「権限」の問題です。サーバーはあなたを認識していますが、必要な「権限(Capability)」(
edit_postsなど)が不足しています。 - Postmanによる切り分け: Postmanを使用して、Basic AuthとApplication Passwordを用いたPOSTリクエストを試行してください。これが成功し、自作のアプリで失敗する場合は、アプリ側で
Authorizationヘッダーが正しく送信されていない可能性があります。 - ヘッダー到達の確認: ルートディレクトリに
test.phpファイルを作成し、<?php print_r(getallheaders()); ?>を記述してください。呼び出し時に出力結果からAuthorizationキーが欠落している場合、Webサーバーがそれを削除しています。
解決策1:ネイティブのApplication Passwordsを使用する
バージョン5.6以降、WordPressにはAPI認証用のシステムが標準搭載されています。サードパーティ製のBasic Authプラグインをインストールする必要はもうありません。APIコールに実際の管理者パスワードを使用すると、セキュリティ上の理由でブロックされ、デフォルトでは失敗します。
- ダッシュボードのユーザー > プロフィールに移動します。
- 下部にあるアプリケーションパスワードセクションを探します。
- 「NextJS Frontend」などの名前を入力し、新しいアプリケーションパスワードを追加をクリックします。
- 24文字の文字列をすぐに保存してください。二度と表示されません。
リクエストを行う際は、ユーザー名とこの24文字の文字列を認証情報として使用します。スタックの他の部分で高エントロピーなキーを生成する必要がある場合は、Password Generatorが役立ちますが、この特定のタスクに関しては、WordPressが提供するものを使用してください。
解決策2:Apacheによるヘッダー削除の修正
Apacheは、401エラーの最も一般的な原因です。多くの共有ホストやデフォルト設定では、認証情報の漏洩を防ぐためにAuthorizationヘッダーを削除します。その結果、WordPressはリクエストを受信してもログイン情報がないものとして扱います。
.htaccessファイルを開き、# BEGIN WordPressブロックの直前、一番上の行に以下のコードを挿入してください。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{1}]
</IfModule>
このディレクティブはヘッダーをキャプチャし、$_SERVER['HTTP_AUTHORIZATION']変数に渡します。これが設定されると、WordPressはついにApplication Passwordを認識できるようになります。
解決策3:Nginx設定の調整
Nginxは通常、ヘッダーを確実に渡しますが、特定のFastCGI構成ではドロップされることがあります。Nginxを使用している場合は、サイト設定ファイル(通常は/etc/nginx/sites-available/にあります)を確認してください。PHPブロックに以下の行が含まれていることを確認します。
fastcgi_pass_header Authorization;
ファイルを保存した後、sudo nginx -tで設定をテストし、sudo systemctl reload nginxを使用してサービスを再読み込みしてください。
解決策4:ローカルAJAXリクエストの認証
カスタムプラグインやGutenbergブロックなど、スクリプトがWordPressエコシステム内で動作している場合は、Application Passwordsを使用せず、代わりにNonceを使用してください。これはセッションを現在ログインしているユーザーに紐付けるため、フロントエンドスクリプトにとってより安全です。
まず、PHPからJavaScriptにnonceを渡します。
wp_localize_script( 'my-handle', 'wpSettings', [
'nonce' => wp_create_nonce( 'wp_rest' )
]);
次に、JavaScriptのfetch呼び出しにX-WP-Nonceヘッダーを含めます。
fetch('/wp-json/wp/v2/posts/42', {
method: 'POST',
headers: {
'X-WP-Nonce': wpSettings.nonce,
'Content-Type': 'application/json'
},
body: JSON.stringify({ status: 'publish' })
});
接続の確認
curlを使用して修正を確認してください。これにより、CORSやキャッシュされたヘッダーなどのブラウザ関連の問題を排除できます。ターミナルで以下のコマンドを実行してください。
curl -X POST https://your-site.com/wp-json/wp/v2/posts \
-u "username:xxxx-xxxx-xxxx-xxxx-xxxx-xxxx" \
-H "Content-Type: application/json" \
-d '{"title":"Connection Test","status":"draft"}'
修正が成功すると、201 Createdステータスコードが返されます。403が返される場合は、ユーザーアカウントに「記事編集(Edit Posts)」権限があることを確認してください。サーバーファイルを管理しており、フォルダ権限を確認する必要がある場合は、Unix Permissions Calculatorを使用して、wp-contentフォルダが厳しく制限されすぎていないか(通常は755)を確認するのに便利です。
重要なポイントのまとめ
- コードよりもサーバー: REST APIの401エラーの90%は、ApacheまたはNginxがヘッダーを削除していることが原因です。
- セキュリティプラグインの確認: Wordfenceや「All In One WP Security」などのツールは、REST APIを完全に無効化することがあります。手動での修正が失敗した場合は、これらの設定を確認してください。
- 権限(Capability)の重要性: 認証(本人確認)と承認(何ができるか)は異なります。ユーザーが正しいWordPressロールを持っていることを確認してください。

