All Products
Search
Document Center

Alibaba Cloud Service Mesh:Implementasikan CORS di ASM

Last Updated:Mar 11, 2026

Ketika aplikasi frontend mengirim permintaan HTTP ke layanan backend yang berada di domain atau port berbeda, browser secara default memblokir respons tersebut. Berbagi sumber daya lintas asal (CORS) memungkinkan Anda mengontrol origin, metode, dan header yang dapat diterima oleh layanan Anda. Di Service Mesh (ASM), Anda menambahkan blok corsPolicy ke VirtualService, dan proxy sidecar Envoy akan menangani negosiasi secara otomatis—tanpa perlu mengubah kode aplikasi.

Referensi corsPolicy

Tambahkan blok corsPolicy ke bagian http dari VirtualService. ASM menerapkan kebijakan ini pada tingkat proxy sidecar Envoy dan menangani permintaan simple maupun preflight secara otomatis.

Klik untuk melihat contoh 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"

Bidang

BidangDeskripsi
allowOriginsOrigin yang diizinkan mengakses layanan. Setiap entri merupakan StringMatch dengan salah satu dari tiga jenis pencocokan: exact (pencocokan string eksak), prefix (pencocokan berdasarkan awalan), atau regex (ekspresi reguler sintaks RE2). Untuk permintaan tanpa kredensial, atur nilai ini ke wildcard (*) untuk mengizinkan semua origin.
allowMethodsMetode HTTP yang diizinkan untuk permintaan lintas asal. Dipetakan ke header respons Access-Control-Allow-Methods.
allowHeadersHeader permintaan yang diizinkan dalam permintaan lintas asal. Dipetakan ke header respons Access-Control-Allow-Headers.
exposeHeadersHeader respons yang boleh diakses oleh browser. Dipetakan ke header respons Access-Control-Expose-Headers.
maxAgeDurasi browser dapat menyimpan cache respons preflight. Dipetakan ke header respons Access-Control-Max-Age. Contoh: "24h".
allowCredentialsApakah permintaan lintas asal boleh menyertakan kredensial (cookie, header otorisasi, atau sertifikat klien TLS).
Penting

Ketika allowCredentials diatur ke true, jangan gunakan wildcard (*) untuk allowOrigins, allowHeaders, atau allowMethods. Browser akan menolak respons yang menggabungkan kredensial dengan nilai wildcard. Sebagai gantinya, tentukan origin secara eksplisit.

Aktifkan CORS untuk akses lintas asal

Langkah-langkah berikut mendeploy aplikasi frontend dan backend pada gerbang masuk terpisah, lalu menambahkan kebijakan CORS agar frontend dapat mengakses backend lintas asal. Alur kerjanya adalah:

  1. Deploy aplikasi backend dan frontend.

  2. Buat dua gerbang masuk untuk mensimulasikan origin yang berbeda.

  3. Siapkan aturan routing untuk kedua aplikasi.

  4. Konfirmasi bahwa permintaan lintas asal gagal tanpa CORS.

  5. Tambahkan corsPolicy dan verifikasi bahwa permintaan berhasil.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

Langkah 1: Deploy aplikasi

Deploy aplikasi backend

  1. Dapatkan file kubeconfig kluster Anda dan hubungkan dengan kubectl.

  2. Buat file bernama 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. Deploy aplikasi di namespace default:

       kubectl apply -f details.yaml -n default

Deploy aplikasi frontend

  1. Buat file bernama 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. Deploy aplikasi di namespace foo:

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

Langkah 2: Deploy gerbang masuk

Buat dua gerbang masuk agar frontend dan backend dapat diakses melalui alamat IP berbeda, mensimulasikan origin yang berbeda.

  1. Masuk ke Konsol ASM. Di panel navigasi sebelah kiri, pilih Service Mesh > Mesh Management.

  2. Pada halaman Mesh Management, klik nama instans ASM. Di panel navigasi sebelah kiri, pilih ASM Gateways > Ingress Gateway.

  3. Pada halaman Ingress Gateway, klik Create.

  4. Pada halaman Create, atur Name menjadi ingressgateway. Pilih kluster target dari daftar drop-down Cluster. Atur CLB Instance Type ke Internet Access. Pilih tipe instans Classic Load Balancer (CLB) di bawah Create a CLB Instance. Biarkan parameter lainnya tetap default, lalu klik Create.

  5. Ulangi langkah 3 dan 4 untuk membuat gerbang masuk kedua bernama ingressgateway2.

Langkah 3: Buat aturan routing

Rutekan traffic ke aplikasi backend

  1. Buat gateway Istio yang mengaitkan layanan details dengan gateway ingressgateway.

    1. Pada halaman detail instans ASM, pilih ASM Gateways > Gateway di panel navigasi sebelah kiri. Pada halaman Gateway, klik Create from YAML.

    2. Pilih default dari daftar drop-down Namespace, lalu tempel YAML berikut dan klik Create:

      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. Buat VirtualService untuk backend.

    1. Pada halaman detail instans ASM, pilih Traffic Management Center > VirtualService di panel navigasi sebelah kiri. Klik Create from YAML.

    2. Pilih default dari daftar drop-down Namespace, lalu tempel YAML berikut dan klik Create:

      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. Verifikasi bahwa backend dapat diakses.

    1. Dapatkan alamat IP gateway ingressgateway. Untuk detailnya, lihat Buat ingress gateway.

    2. Buka http://<ingressgateway-ip>/details/2 di browser Anda. Backend response from the details service Respons JSON menunjukkan bahwa backend dapat dijangkau.

Rutekan traffic ke aplikasi frontend

  1. Buat gateway Istio yang mengaitkan layanan istio-cors-demo dengan gateway ingressgateway2.

    1. Pada halaman detail instans ASM, pilih ASM Gateways > Gateway di panel navigasi sebelah kiri. Klik Create from YAML.

    2. Pilih foo dari daftar drop-down Namespace, lalu tempel YAML berikut dan klik Create:

      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. Buat VirtualService untuk frontend.

    1. Pada halaman detail instans ASM, pilih Traffic Management Center > VirtualService di panel navigasi sebelah kiri. Klik Create from YAML.

    2. Pilih foo dari daftar drop-down Namespace, lalu tempel YAML berikut dan klik Create:

      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

Konfirmasi bahwa permintaan lintas asal gagal tanpa CORS

  1. Dapatkan alamat IP gateway ingressgateway2. Untuk detailnya, lihat Buat ingress gateway.

  2. Buka http://<ingressgateway2-ip> di Google Chrome.

  3. Pada kolom URL di halaman tersebut, masukkan http://<ingressgateway-ip>/details/2 dan klik Send.

    Frontend URL field and Send button

  4. Buka Chrome DevTools (F12, atau More tools > Developer tools). Konsol menampilkan error CORS. Frontend pada ingressgateway2 mengirim permintaan lintas asal ke backend pada ingressgateway, dan belum ada kebijakan CORS yang diterapkan.

    CORS error in Chrome DevTools

Langkah 4: Tambahkan kebijakan CORS

  1. Masuk ke Konsol ASM. Di panel navigasi sebelah kiri, pilih Service Mesh > Mesh Management.

  2. Klik nama instans ASM. Pilih Traffic Management Center > VirtualService di panel navigasi sebelah kiri.

  3. Pada halaman VirtualService, temukan virtual service bookinfo dan klik YAML di kolom Actions.

  4. Pada dialog Edit, tambahkan blok corsPolicy berikut ke bidang http dan klik OK: Ganti <ingressgateway2-ip> dengan alamat IP aktual gateway ingressgateway2.

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

    CORS policy added to the VirtualService YAML

Langkah 5: Verifikasi kebijakan CORS

  1. Buka http://<ingressgateway2-ip> di Google Chrome.

  2. Pada kolom URL, masukkan http://<ingressgateway-ip>/details/2 dan klik Send. Frontend kini berhasil mengambil data dari backend. Kebijakan CORS telah berlaku.

    Successful cross-origin response

Cara kerja CORS

CORS menggunakan header HTTP agar server dapat mendeklarasikan origin, metode, dan header yang diizinkan. Bergantung pada permintaannya, browser mengikuti salah satu dari dua alur: permintaan simple atau permintaan preflight.

Permintaan simple

Browser menambahkan header Origin dan langsung mengirim permintaan tersebut. Server mengevaluasi origin dan mengembalikan header Access-Control-Allow-Origin dan Access-Control-Allow-Methods dalam respons.

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

Permintaan dikategorikan sebagai permintaan simple hanya jika semua kondisi berikut terpenuhi:

  • Metode HTTP adalah GET, HEAD, atau POST.

  • Header Content-Type (jika diatur) bernilai text/plain, application/x-www-form-urlencoded, atau multipart/form-data.

  • Satu-satunya header yang diatur secara manual adalah header yang termasuk dalam daftar aman CORS menurut standar Fetch: Accept, Accept-Language, Content-Language, dan Content-Type (terbatas pada nilai-nilai di atas).

Permintaan preflight

Jika salah satu kondisi di atas tidak terpenuhi, browser mengirim permintaan preflight—permintaan HTTP OPTIONS—sebelum permintaan sebenarnya. Preflight memverifikasi apakah server menerima metode, header, dan origin yang dimaksud.

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

Jika server mengizinkan permintaan tersebut, browser melanjutkan dengan permintaan lintas asal yang sebenarnya. Jika tidak, browser memblokirnya.

Pertimbangan keamanan

  • Hindari origin wildcard saat menggunakan kredensial. Ketika allowCredentials bernilai true, browser menolak respons yang mengatur Access-Control-Allow-Origin ke *. Sebagai gantinya, tentukan origin secara eksplisit.

  • Batasi metode yang diizinkan. Izinkan hanya metode HTTP yang benar-benar dibutuhkan layanan Anda. Hindari menambahkan DELETE atau PATCH kecuali benar-benar diperlukan.

  • Atur maxAge yang wajar. Menyimpan cache respons preflight mengurangi latensi untuk permintaan lintas asal berulang, tetapi durasi cache yang terlalu lama dapat menunda penerapan perubahan kebijakan. Nilai antara 1h dan 24h cocok untuk sebagian besar kasus penggunaan.

  • Lebih baik gunakan pencocokan exact atau prefix daripada regex. Pola regex yang terlalu luas dapat secara tidak sengaja mengizinkan origin yang tidak tepercaya. Uji pola regex sebelum menerapkannya di lingkungan produksi.