2026年5月22日
2026年5月22日
WordPress REST APIが動作しない問題を解決する方法
はじめに
WordPressのREST APIを使おうとすると{"code":"rest_no_route","message":"一致するルートが見つかりませんでした"}エラーが返る・/wp-json/wp/v2/postsにアクセスすると403 Forbiddenになる・カスタム投稿タイプがREST APIのエンドポイントに出てこない・JWT認証プラグインを使っているがトークンを渡しても401 Unauthorizedが返るといった問題は、パーマリンク設定・show_in_restフラグ・REST API無効化プラグイン・認証ヘッダーの設定が原因です。
症状・原因
- パーマリンクが「基本」設定のためREST APIのURLが解決できない
- セキュリティプラグインやWAFがREST APIへのアクセスをブロックしている
- カスタム投稿タイプの
register_post_type()でshow_in_restをfalseにしている - Apache/Nginxが
AuthorizationヘッダーをPHPに渡していない
解決手順
ステップ1:REST APIの動作を診断する
# REST APIの基本動作確認
curl -s https://example.com/wp-json/ | python -m json.tool | head -20
# 投稿一覧の取得テスト
curl -s https://example.com/wp-json/wp/v2/posts?per_page=1
# 認証付きリクエスト(Application Passwordsを使用)
curl -s -u "username:application_password" \
https://example.com/wp-json/wp/v2/users/me
# wp-cli でREST APIルート一覧を確認
wp eval "
\$server = rest_get_server();
\$routes = \$server->get_routes();
foreach (array_keys(\$routes) as \$route) {
if (strpos(\$route, '/wp/v2/') !== false) {
echo \$route . PHP_EOL;
}
}
"
ステップ2:REST APIを妨害している設定を修正する
// REST APIを無効化しているフィルターを確認・削除
// ✗ 以下のようなコードが functions.php にないか確認
add_filter('rest_authentication_errors', fn() => new WP_Error('rest_disabled', 'REST API disabled'));
// ✓ REST APIへのアクセスを特定エンドポイントのみ制限する正しい方法
add_filter('rest_authentication_errors', function(WP_Error|true|null $result): WP_Error|true|null {
if (! is_user_logged_in() && ! str_starts_with(rest_get_url_prefix(), 'wp-json')) {
return new WP_Error('rest_not_logged_in', '認証が必要です', ['status' => 401]);
}
return $result;
});
# Apache: Authorization ヘッダーを PHP に渡す(.htaccess)
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# または
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
ステップ3:カスタム投稿タイプをREST APIに対応させる
// register_post_type() で show_in_rest を有効化
register_post_type('product', [
'label' => '商品',
'public' => true,
'show_in_rest' => true, // REST API に公開
'rest_base' => 'products', // /wp-json/wp/v2/products
'rest_controller_class' => 'WP_REST_Posts_Controller',
'supports' => ['title', 'editor', 'thumbnail', 'custom-fields'],
]);
// カスタムフィールドを REST API に公開
register_post_meta('product', 'price', [
'show_in_rest' => true,
'single' => true,
'type' => 'number',
'auth_callback' => fn() => current_user_can('edit_posts'),
]);
ステップ4:カスタム REST API エンドポイントを作成する
// カスタムエンドポイントの登録
add_action('rest_api_init', function(): void {
register_rest_route('myplugin/v1', '/items/(?P<id>\d+)', [
'methods' => WP_REST_Server::READABLE, // GET
'callback' => 'my_rest_get_item',
'permission_callback' => fn() => current_user_can('read'),
'args' => [
'id' => [
'validate_callback' => fn(string $v) => is_numeric($v),
'sanitize_callback' => 'absint',
'required' => true,
],
],
]);
});
function my_rest_get_item(WP_REST_Request $request): WP_REST_Response|WP_Error {
$item = get_post($request->get_param('id'));
if (! $item instanceof WP_Post) {
return new WP_Error('not_found', '見つかりません', ['status' => 404]);
}
return rest_ensure_response(['id' => $item->ID, 'title' => $item->post_title]);
}
ステップ5:REST API 認証とApplication Passwordsを設定する
# Application Passwords を有効化(WordPress 5.6+)
# 管理画面 → ユーザー → プロフィール → アプリケーションパスワード で生成
# 生成したパスワードで認証テスト
APP_PASS="xxxx xxxx xxxx xxxx xxxx xxxx"
curl -s -u "admin:${APP_PASS}" \
-X POST https://example.com/wp-json/wp/v2/posts \
-H "Content-Type: application/json" \
-d '{"title":"テスト投稿","status":"draft"}'
// REST API レスポンスにカスタムフィールドを追加
add_filter('rest_prepare_post', function(WP_REST_Response $response, WP_Post $post): WP_REST_Response {
$response->data['custom_field'] = get_post_meta($post->ID, 'custom_field', true);
return $response;
}, 10, 2);
注意事項
- パーマリンクを「基本」(
?p=123形式)に設定しているとREST APIのURLが機能しません。「投稿名」などのモダンなパーマリンク構造に変更してください - セキュリティプラグイン(iThemes Security、WordFence等)がREST APIへの未認証アクセスをブロックしている場合があります。プラグインの設定でREST APIを許可してください
permission_callbackに__return_trueを設定すると認証なしでアクセス可能になります。本番環境では必ず適切な権限チェックを実装してください
まとめ
WordPress REST API不動作の解決は①curlでREST APIレスポンスを確認・wp evalでルート一覧を取得・パーマリンク設定が「基本」でないか確認、②セキュリティプラグインのREST API無効化フィルターを削除・Apacheの.htaccessでAuthorizationヘッダーをPHPに渡す・NginxはfastcgiパラメーターにHTTP_AUTHORIZATIONを追加、③register_post_type()のshow_in_rest=trueでカスタム投稿タイプを公開・register_post_meta()のshow_in_rest=trueでカスタムフィールドを公開、④register_rest_route()でカスタムエンドポイントを作成・permission_callbackで権限チェック・validate_callback/sanitize_callbackで入力値を検証、⑤Application Passwordsでトークンレスな認証・rest_prepare_{type}フィルターでレスポンスにカスタムデータを追加の手順で解決します。