Nginx CORS設定

Nginxでadd_headerディレクティブ、複数オリジン用mapブロック、適切なOPTIONS処理を使用してCORSヘッダーを設定します。本番環境対応のスニペット付き。

Framework Config

詳細な説明

Nginx CORS — 本番環境設定

Nginxはアプリケーションサーバーの前のリバースプロキシとしてよく使用されます。NginxレイヤーでCORSヘッダーを追加することで、アプリケーションコードでCORSを処理する必要がなくなります。

シンプルな設定 — 単一オリジン

server {
    listen 443 ssl;
    server_name api.example.com;

    location /api/ {
        add_header Access-Control-Allow-Origin "https://app.example.com" always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
        add_header Access-Control-Max-Age 3600 always;
        add_header Access-Control-Allow-Credentials "true" always;
        add_header Vary Origin always;

        if ($request_method = 'OPTIONS') {
            return 204;
        }

        proxy_pass http://backend;
    }
}

mapを使った複数オリジン

map $http_origin $cors_origin {
    default "";
    "https://app.example.com"   "$http_origin";
    "https://admin.example.com" "$http_origin";
    "https://staging.example.com" "$http_origin";
}

server {
    location /api/ {
        if ($cors_origin != "") {
            add_header Access-Control-Allow-Origin $cors_origin always;
            add_header Access-Control-Allow-Credentials "true" always;
            add_header Vary Origin always;
        }

        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin $cors_origin always;
            add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
            add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
            add_header Access-Control-Max-Age 3600 always;
            return 204;
        }

        proxy_pass http://backend;
    }
}

alwaysパラメータ

alwaysパラメータはエラーレスポンス(4xx、5xx)でもヘッダーを追加することを保証します。これがないと、Nginxは2xxと3xxレスポンスにのみカスタムヘッダーを追加し、401/403レスポンスでのCORSエラーに正しいヘッダーが含まれず、デバッグが非常に困難になります。

よくある間違い

  1. alwaysの欠落 — エラーレスポンスでヘッダーが送信されない。
  2. ヘッダーの重複 — NginxとバックエンドがCORSヘッダーを設定すると、ブラウザが重複値を検出して拒否する可能性があります。CORSは1つのレイヤーでのみ処理してください。
  3. ifディレクティブの制限 — Nginxのifはリライトフェーズで評価されます。複雑な条件にはmapを使用してください。

ユースケース

マイクロサービスアーキテクチャをNginxの背後にデプロイするオペレーションエンジニアが、個々のバックエンドサービスがCORSロジックを実装しなくて済むように、リバースプロキシレイヤーでCORSヘッダーを追加する必要があります。

試してみる — CORS Header Builder

フルツールを開く