あるオリジンの Web ページが、Container Service for Kubernetes (ACK) クラスター内のサービスにアクセスしようとすると、リクエストがブラウザの同一生成元ポリシーによってブロックされ、blocked by CORS policy というエラーが表示されることがあります。このポリシーは、ドメイン、プロトコル、またはポートが異なる場合に適用されます。例えば、https://example.com 上のスクリプトが https://api.example.com を呼び出そうとする場合です。この問題を解決するには、NGINX Ingress に CORS 関連のアノテーションを追加し、ブラウザがクロスオリジンレスポンスを受け入れられるように設定します。その際、過度に寛容な設定を使用するのではなく、許可するオリジン、メソッド、ヘッダーを明示的に設定することが重要です。
仕組み
CORS は、シンプルリクエストとプリフライトリクエストの 2 種類があります。シンプルリクエストはサーバーに直接送信されますが、プリフライトリクエストでは、ブラウザはまず予備的な OPTIONS リクエストを送信する必要があります。このプリフライトは、実際のリクエストを送信する前に、サーバーがリクエストを受け入れるかを確認するためのチェックとしての役割を果たします。
以下のいずれかの条件が満たされる場合、リクエストはプリフライトされます。
GET、HEAD、またはPOST以外のメソッドを使用する場合。Content-Typeがtext/plain、application/x-www-form-urlencoded、またはmultipart/form-data以外のPOSTリクエストである場合。カスタムヘッダーを含む場合。
ブラウザが NGINX Ingress にシンプルリクエストを送信する場合:
ブラウザはリクエストに
Originヘッダーを追加し、そのソース (例:Origin: https://example.com) を示します。NGINX Ingress Controller は、リクエストの HTTP メソッドと
Originヘッダーの値を CORS 設定と比較し、一致する場合、レスポンスにAccess-Control-Allow-Originヘッダーを含めます。このヘッダーの値は、リクエストのOriginヘッダーを反映します。ブラウザはレスポンスを受信し、
Access-Control-Allow-Originヘッダーの値がページのオリジンと一致するかどうかを確認します。一致する場合、リクエストは成功します。一致しない場合、またはヘッダーがない場合、ブラウザはリクエストをブロックします。
プリフライトリクエストは、実際のリクエストが送信される前に、次のステップに従います。
ブラウザは、意図するメインリクエストのメソッド (
Access-Control-Request-Method) とヘッダー (Access-Control-Request-Headers) を含むOPTIONSリクエストを送信します。NGINX Ingress は、CORS 設定が
OPTIONSリクエストのメソッドとヘッダーを許可するかどうかをチェックします。リクエストされたメソッドまたはいずれかのヘッダーが許可値のリストにない場合、プリフライトリクエストは失敗し、ブラウザはメインリクエストを送信しません。
手順
ステップ 1: CORS の設定
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] を選択します。
[クラスター] ページで、クラスター名をクリックします。左側のナビゲーションウィンドウで、 を選択します。
[Ingress] ページで、Ingress を見つけ、[操作] 列の [YAML の編集] をクリックします。
ユースケースに基づいて NGINX Ingress を設定します。詳細については、「NGINX Ingress Controller の一般的な CORS アノテーション」をご参照ください。
認証情報を含むクロスオリジンリクエスト
これは、一般的なフロントエンドとバックエンドの分離ユースケースに適用されます。フロントエンドアプリケーション (https://example.com または https://app.example.com) は、Cookie や Authorization ヘッダーなどの認証情報を使用してバックエンド API (https://api.example.com) にアクセスする必要があります。
Ingress の YAML ファイルに次の annotations を追加します。この例では、https://example.com および https://app.example.com オリジンからの GET、POST、およびその他のメソッドのクロスオリジンアクセスを有効にします。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress-secure
annotations:
# CORS を有効化する。
nginx.ingress.kubernetes.io/enable-cors: "true"
# Cookie や Authorization ヘッダーなどの認証情報を含むリクエストを許可する。
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
# クロスオリジンリクエストで許可されるオリジンドメインを指定する。認証情報を使用する場合、 "*" は使用できません。
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com, https://app.example.com"
# 許可される HTTP メソッド。
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
# 許可されるリクエストヘッダー。Authorization など、サービスで必要なカスタムヘッダーを含める必要がある。
nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type, Authorization"
# フロントエンドに公開されるカスタムレスポンスヘッダーを指定する。
nginx.ingress.kubernetes.io/cors-expose-headers: "X-Request-ID, Content-Length, Content-Range"
# プリフライトリクエストキャッシュの最大有効期間 (秒単位) を設定する (例: 24 時間の場合は 86400)。
nginx.ingress.kubernetes.io/cors-max-age: "86400"
...認証情報を含まないクロスオリジンリクエスト
これは、認証を必要としないパブリックな読み取り専用リクエストに適用されます。
YAML ファイルに、次の annotations 設定を追加します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress-secure
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
# オリジンが "*" の場合、認証情報は "false" にする必要がある。
nginx.ingress.kubernetes.io/cors-allow-credentials: "false"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, HEAD"
...ステップ 2: CORS 設定の検証
curl を使用して、ブラウザが送信する OPTIONS プリフライトリクエストをシミュレートします。
curl -i -X OPTIONS 'https://api.example.com/your/path' \
-H 'Origin: https://app.example.com' \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization'期待される出力: 成功したリクエストは 2xx ステータスコード (通常は 204 No Content または 200 OK) を返します。
HTTP/2 204
date: Fri, 12 Sep 2025 03:51:12 GMT
access-control-allow-origin: https://example.com, https://app.example.com
access-control-allow-credentials: true
access-control-allow-methods: GET, POST, PUT, DELETE, OPTIONS
access-control-allow-headers: Content-Type, Authorizationレスポンスの access-control-allow-* ヘッダーが、Ingress リソースの nginx.ingress.kubernetes.io/cors-* アノテーションと一致することを確認してください。
NGINX Ingress Controller の一般的な CORS アノテーション
アノテーション | 説明 | 対応する HTTP ヘッダー | 例 |
| CORS ポリシーを有効にするかどうかを指定します。 |
| |
| リソースにアクセスできるオリジンを指定します。複数のドメインをカンマ区切りでリストできます。 | Access-Control-Allow-Origin |
|
|
| Access-Control-Allow-Methods |
|
| 許可されるカスタムリクエストヘッダーを指定します。 | Access-Control-Allow-Headers |
|
| Cookie や HTTP 認証などの認証情報を使用してリクエストを送信できるかどうかを指定します。 | Access-Control-Allow-Credentials |
|
| ブラウザがアクセスできるレスポンスヘッダーを指定します。 このアノテーションには NGINX Ingress Controller v0.44 以降が必要です。 | Access-Control-Expose-Headers |
|
| プリフライトレスポンスをブラウザがキャッシュできる最大時間 (秒単位) です。この期間が長いほど、プリフライトリクエストの頻度が減ります。セキュリティ要件が厳しい場合は、より短い値を設定することを検討してください。 | Access-Control-Max-Age |
|
よくある質問
CORS を設定した後も、クロスオリジンエラーが発生するのはなぜですか?
ブラウザの開発者ツールでネットワークリクエストを確認するか、NGINX Ingress Controller のログを確認してください。リクエストのオリジン、メソッド、およびヘッダーがすべて Ingress の CORS 構成で許可されていることを確認してください。
以下は、典型的な CORS エラーメッセージです。この場合、リクエストは POST メソッドを使用しましたが、POST はプリフライトレスポンスの Access-Control-Allow-Methods ヘッダーに含まれていませんでした。
Method POST is not allowed by Access-Control-Allow-Methods in preflight responseAccess to fetch at 'https://api.example.com/data' from origin 'https://app.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: xxxx.
nginx.ingress.kubernetes.io/cors-allow-credentials: "true" を設定した後、nginx.ingress.kubernetes.io/cors-allow-origin を "*" に設定できますか?
いいえ。これはブラウザによって強制されるセキュリティ上の制限です。リクエストに認証情報 (Cookie など) が含まれている場合、サーバーは信頼できるオリジンを明示的に指定する必要があり、ワイルドカード (*) を使用することはできません。このポリシーは、悪意のある Web サイトがユーザーの認証情報を使用してサーバーに不正なリクエストを送信することを防ぎます。
同一ドメイン内の異なるパス (例: /api/public/* と /api/private/*) に対して、異なる CORS ポリシーを設定するにはどうすればよいですか?
Ingress リソース上の CORS アノテーションは、その中で定義されているすべてのパスに適用されます。異なるパスに異なるポリシーを設定するには、パスグループごとに個別の Ingress リソースを作成し、それぞれに目的の CORS アノテーションを適用する必要があります。たとえば、api-public-ingress.yaml と api-private-ingress.yaml を作成し、それぞれに異なる CORS アノテーションを設定します。
クライアント側のアプリケーションがカスタムレスポンスヘッダーにアクセスするにはどうすればよいですか?
デフォルトでは、クロスオリジンリクエストを処理する際、ブラウザは限られた標準レスポンスヘッダー (Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma) にしかアクセスできません。サーバーから送信されるカスタムヘッダー (例:X-Request-ID) は、デフォルトではクライアント側の JavaScript からアクセスできません。
カスタムヘッダーにアクセスするには、nginx.ingress.kubernetes.io/cors-expose-headers アノテーションを使用して Access-Control-Expose-Headers HTTP レスポンスヘッダーを設定します。このヘッダーは、クライアント側のコードがどの非標準のレスポンスヘッダーにアクセスできるかをブラウザに伝えます。詳細については、「認証情報を含むクロスオリジンリクエスト」をご参照ください。
関連ドキュメント
このトピックでは、NGINX Ingress Controller の一般的な CORS アノテーションの例のみを記載しています。完全なリストについては、「Enable CORS」をご参照ください。