すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:ASM での CORS の実装

最終更新日:Mar 11, 2026

フロントエンドアプリケーションが異なるドメインまたはポート上のバックエンドサービスに HTTP リクエストを送信すると、ブラウザはデフォルトでその応答をブロックします。オリジン間リソース共有 (CORS) を使用すると、どのオリジン、メソッド、ヘッダーからのアクセスをサービスが受け入れるかを制御できます。Service Mesh (ASM) では、corsPolicy ブロックを VirtualService に追加することで、Envoy サイドカーがネゴシエーションを自動的に処理します。アプリケーションコードの変更は不要です。

corsPolicy リファレンス

corsPolicy ブロックを VirtualService の http セクションに追加します。ASM はこのポリシーを Envoy サイドカーのレベルで適用し、シンプルリクエストとプレフライトリクエストの両方を自動的に処理します。

サンプル VirtualService を表示するにはクリックしてください

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings-route
spec:
  hosts:
  - ratings.prod.svc.cluster.local
  http:
  - route:
    - destination:
        host: ratings.prod.svc.cluster.local
        subset: v1
    corsPolicy:
      allowOrigins:
      - exact: https://example.com
      - regex: "https://.*\\.example\\.com"
      allowMethods:
      - POST
      - GET
      allowCredentials: false
      allowHeaders:
      - X-Foo-Bar
      maxAge: "24h"

フィールド

フィールド説明
allowOriginsサービスへのアクセスを許可するオリジン。各エントリは、次のいずれかのマッチタイプを持つ StringMatch です:exact(完全一致)、prefix(プレフィックスベースの一致)、または regex(RE2 構文の正規表現)。認証情報なしのリクエストの場合、すべてのオリジンを許可するにはワイルドカード (*) を設定します。
allowMethodsクロスオリジンリクエストで許可される HTTP メソッド。Access-Control-Allow-Methods レスポンスヘッダーに対応します。
allowHeadersクロスオリジンリクエストで許可されるリクエストヘッダー。Access-Control-Allow-Headers レスポンスヘッダーに対応します。
exposeHeadersブラウザがアクセス可能なレスポンスヘッダー。Access-Control-Expose-Headers レスポンスヘッダーに対応します。
maxAgeブラウザがプレフライトレスポンスをキャッシュできる期間。Access-Control-Max-Age レスポンスヘッダーに対応します。例:"24h"
allowCredentialsクロスオリジンリクエストに認証情報(クッキー、Authorization ヘッダー、TLS クライアント証明書)を含められるかどうかを指定します。
重要

allowCredentialstrue に設定されている場合、allowOriginsallowHeaders、または allowMethods にワイルドカード (*) を使用しないでください。ブラウザは、認証情報とワイルドカード値を組み合わせた応答を拒否します。代わりに、明示的なオリジンを指定してください。

クロスオリジンアクセスのための CORS 有効化

以下の手順では、フロントエンドおよびバックエンドアプリケーションを個別のイングレスゲートウェイ上にデプロイし、フロントエンドがオリジンをまたいでバックエンドにアクセスできるように CORS ポリシーを追加します。ワークフローは次のとおりです。

  1. バックエンドおよびフロントエンドアプリケーションをデプロイします。

  2. 異なるオリジンをシミュレートするために、2 つのイングレスゲートウェイを作成します。

  3. 両方のアプリケーションのルーティングルールを設定します。

  4. CORS がない状態でクロスオリジンリクエストが失敗することを確認します。

  5. corsPolicy を追加し、リクエストが成功することを検証します。

前提条件

作業を開始する前に、次の要件を満たしていることを確認してください。

ステップ 1:アプリケーションのデプロイ

バックエンドアプリケーションのデプロイ

  1. ご利用のクラスターの kubeconfig ファイルを取得し、kubectl で接続します

  2. details.yaml という名前のファイルを作成します。

    details.yaml

       apiVersion: v1
       kind: Service
       metadata:
         name: details
         labels:
           app: details
           service: details
       spec:
         ports:
         - port: 9080
           name: http
         selector:
           app: details
       ---
       apiVersion: v1
       kind: ServiceAccount
       metadata:
         name: bookinfo-details
         labels:
           account: details
       ---
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: details-v1
         labels:
           app: details
           version: v1
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: details
             version: v1
         template:
           metadata:
             labels:
               app: details
               version: v1
           spec:
             serviceAccountName: bookinfo-details
             containers:
             - name: details
               image: docker.io/istio/examples-bookinfo-details-v1:1.16.4
               imagePullPolicy: IfNotPresent
               ports:
               - containerPort: 9080
               securityContext:
                 runAsUser: 1000
  3. default 名前空間にアプリケーションをデプロイします。

       kubectl apply -f details.yaml -n default

フロントエンドアプリケーションのデプロイ

  1. istio-cors-demo.yaml という名前のファイルを作成します。

    istio-cors-demo.yaml

       apiVersion: v1
       kind: ServiceAccount
       metadata:
         name: istio-cors-demo
       ---
       apiVersion: v1
       kind: Service
       metadata:
         name: istio-cors-demo
         labels:
           app: istio-cors-demo
           service: istio-cors-demo
       spec:
         ports:
           - name: http
             port: 8000
             targetPort: 80
         selector:
           app: istio-cors-demo
       ---
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: istio-cors-demo
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: istio-cors-demo
             version: v1
         template:
           metadata:
             labels:
               app: istio-cors-demo
               version: v1
           spec:
             serviceAccountName: istio-cors-demo
             containers:
               - image: registry.cn-hangzhou.aliyuncs.com/build-test/istio-cors-demo:v1.0-g8e215f6-aliyun
                 imagePullPolicy: IfNotPresent
                 name: istio-cors-demo
                 ports:
                   - containerPort: 80
  2. foo 名前空間にアプリケーションをデプロイします。

       kubectl apply -f istio-cors-demo.yaml -n foo

ステップ 2:イングレスゲートウェイのデプロイ

フロントエンドとバックエンドを異なる IP アドレスでアクセス可能にして、異なるオリジンをシミュレートするため、2 つのイングレスゲートウェイを作成します。

  1. ASM コンソール にログインします。左側のナビゲーションウィンドウで、Service Mesh > メッシュ管理 を選択します。

  2. メッシュ管理 ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、ASM ゲートウェイ > イングレスゲートウェイ を選択します。

  3. イングレスゲートウェイ ページで、作成 をクリックします。

  4. 作成 ページで、名前ingressgateway を設定します。クラスター ドロップダウンリストから対象のクラスターを選択します。CLB インスタンスタイプインターネットアクセス を設定します。CLB インスタンスの作成 でクラシックロードバランサー (CLB) インスタンスタイプを選択します。残りのパラメーターはデフォルトのままにして、作成 をクリックします。

  5. 手順 3 と 4 を繰り返して、ingressgateway2 という名前の 2 番目のイングレスゲートウェイを作成します。

ステップ 3:ルーティングルールの作成

バックエンドアプリケーションへのトラフィックルーティング

  1. details サービスを ingressgateway ゲートウェイに関連付ける Istio ゲートウェイを作成します。

    1. ASM インスタンスの詳細ページで、左側のナビゲーションウィンドウで ASM ゲートウェイ > ゲートウェイ を選択します。ゲートウェイ ページで、YAML から作成 をクリックします。

    2. 名前空間 ドロップダウンリストで default を選択し、次の YAML を貼り付けて 作成 をクリックします。

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: bookinfo-gateway
        namespace: default
      spec:
        selector:
          istio: ingressgateway
        servers:
          - hosts:
              - '*'
            port:
              name: http
              number: 80
              protocol: HTTP
  2. バックエンド用の VirtualService を作成します。

    1. ASM インスタンスの詳細ページで、左側のナビゲーションウィンドウから [トラフィック管理センター] > [VirtualService] を選択し、[YAML から作成] をクリックします。

    2. 名前空間 ドロップダウンリストで default を選択し、次の YAML を貼り付けて 作成 をクリックします。

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: bookinfo
        namespace: default
      spec:
        gateways:
          - bookinfo-gateway
        hosts:
          - '*'
        http:
          - match:
              - uri:
                  prefix: /details
            route:
              - destination:
                  host: details
                  port:
                    number: 9080
  3. バックエンドにアクセスできることを確認します。

    1. ingressgateway ゲートウェイの IP アドレスを取得します。詳細については、「イングレスゲートウェイの作成」をご参照ください。

    2. ブラウザで http://<ingressgateway-ip>/details/2 を開きます。Backend response from the details service JSON 応答が表示されれば、バックエンドに到達可能であることが確認できます。

フロントエンドアプリケーションへのトラフィックルーティング

  1. istio-cors-demo サービスを ingressgateway2 ゲートウェイに関連付ける Istio ゲートウェイを作成します。

    1. ASM インスタンスの詳細ページで、左側のナビゲーションウィンドウから [ASM ゲートウェイ] > [ゲートウェイ] を選択します。[YAML から作成] をクリックします。

    2. 名前空間 ドロップダウンリストで foo を選択し、次の YAML を貼り付けて 作成 をクリックします。

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: istio-cors-demo-gateway
        namespace: foo
      spec:
        selector:
          istio: ingressgateway2
        servers:
          - hosts:
              - '*'
            port:
              name: http
              number: 80
              protocol: HTTP
  2. フロントエンド用の VirtualService を作成します。

    1. ASM インスタンス詳細ページの左側のナビゲーションウィンドウで、[トラフィック管理センター] > [VirtualService] を選択し、[YAML から作成] をクリックします。

    2. 名前空間 ドロップダウンリストで foo を選択し、次の YAML を貼り付けて 作成 をクリックします。

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: istio-cors-demo
        namespace: foo
      spec:
        gateways:
          - istio-cors-demo-gateway
        hosts:
          - '*'
        http:
          - route:
              - destination:
                  host: istio-cors-demo
                  port:
                    number: 8000

CORS なしでクロスオリジンリクエストが失敗することの確認

  1. ingressgateway2 ゲートウェイの IP アドレスを取得します。詳細については、「イングレスゲートウェイの作成」をご参照ください。

  2. Google Chrome で http://<ingressgateway2-ip> を開きます。

  3. ページの URL 入力欄に http://<ingressgateway-ip>/details/2 を入力し、送信 をクリックします。

    Frontend URL field and Send button

  4. Chrome DevTools を開きます (F12 または その他のツール > デベロッパーツール)。コンソールに CORS エラーが表示されます。ingressgateway2 上のフロントエンドが ingressgateway 上のバックエンドにクロスオリジンリクエストを送信していますが、まだ CORS ポリシーが存在しないためです。

    CORS error in Chrome DevTools

ステップ 4:CORS ポリシーの追加

  1. ASM コンソール にログインします。左側のナビゲーションウィンドウで、Service Mesh > メッシュ管理 を選択します。

  2. ASM インスタンスの名前をクリックします。トラフィック管理センター > VirtualService を左側のナビゲーションウィンドウで選択します。

  3. 仮想サービス」ページで、bookinfo 仮想サービスを見つけ、[操作] 列の [YAML] をクリックします。

  4. 編集 ダイアログボックスで、http フィールドに次の corsPolicy ブロックを追加し、OK をクリックします。<ingressgateway2-ip> は、ingressgateway2 ゲートウェイの実際の IP アドレスに置き換えてください。

       corsPolicy:
         allowCredentials: false
         allowMethods:
           - POST
           - GET
         allowOrigins:
           - prefix: 'http://<ingressgateway2-ip>'
         maxAge: 24h

    CORS policy added to the VirtualService YAML

ステップ 5:CORS ポリシーの検証

  1. Google Chrome で http://<ingressgateway2-ip> を開きます。

  2. URL 入力欄に http://<ingressgateway-ip>/details/2 を入力し、送信 をクリックします。これでフロントエンドがバックエンドからデータを正常に取得できるようになります。CORS ポリシーが有効になっています。

    Successful cross-origin response

CORS の仕組み

CORS は HTTP ヘッダーを使用して、サーバーがどのオリジン、メソッド、ヘッダーを許可するかを宣言できるようにします。リクエストの内容に応じて、ブラウザはシンプルリクエストまたはプレフライトリクエストのいずれかのフローに従います。

シンプルリクエスト

ブラウザは Origin ヘッダーを追加して、リクエストを直接送信します。サーバーはオリジンを評価し、応答に Access-Control-Allow-Origin および Access-Control-Allow-Methods ヘッダーを返します。

GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST

リクエストがシンプルリクエストとして扱われるには、次の条件がすべて満たされている必要があります。

  • HTTP メソッドが GETHEAD、または POST であること。

  • Content-Type ヘッダー(設定されている場合)が text/plainapplication/x-www-form-urlencoded、または multipart/form-data であること。

  • 手動で設定されたヘッダーが Fetch 標準で定義された CORS セーフリストヘッダーのみであること:AcceptAccept-LanguageContent-Language、および Content-Type(上記の値に限定)。

プレフライトリクエスト

上記の条件のいずれかが満たされない場合、ブラウザは実際のリクエストの前にプレフライトリクエスト(HTTP OPTIONS リクエスト)を送信します。プレフライトにより、サーバーが意図したメソッド、ヘッダー、オリジンを受け入れるかどうかが検証されます。

OPTIONS /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 86400

サーバーがリクエストを許可する場合、ブラウザは実際のクロスオリジンリクエストを続行します。許可されない場合は、ブラウザがそれをブロックします。

セキュリティに関する考慮事項

  • 認証情報を使用する際にワイルドカードオリジンを避ける。 allowCredentialstrue の場合、ブラウザは Access-Control-Allow-Origin* に設定された応答を拒否します。代わりに、明示的なオリジンを指定してください。

  • 許可するメソッドを制限する。 サービスに必要な HTTP メソッドのみを許可します。DELETEPATCH は、必要でない限り追加しないでください。

  • 適切な maxAge を設定する。 プレフライトレスポンスをキャッシュすることで、繰り返されるクロスオリジンリクエストの遅延を軽減できますが、キャッシュ期間が長すぎるとポリシー変更の反映が遅れます。ほとんどのユースケースでは、1h24h の値が適しています。

  • regex よりも exact または prefix マッチを優先する。 広範な正規表現パターンは、意図せず信頼できないオリジンを許可してしまう可能性があります。本番環境にデプロイする前に、正規表現パターンをテストしてください。