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.
Bidang
| Bidang | Deskripsi |
|---|---|
allowOrigins | Origin 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. |
allowMethods | Metode HTTP yang diizinkan untuk permintaan lintas asal. Dipetakan ke header respons Access-Control-Allow-Methods. |
allowHeaders | Header permintaan yang diizinkan dalam permintaan lintas asal. Dipetakan ke header respons Access-Control-Allow-Headers. |
exposeHeaders | Header respons yang boleh diakses oleh browser. Dipetakan ke header respons Access-Control-Expose-Headers. |
maxAge | Durasi browser dapat menyimpan cache respons preflight. Dipetakan ke header respons Access-Control-Max-Age. Contoh: "24h". |
allowCredentials | Apakah permintaan lintas asal boleh menyertakan kredensial (cookie, header otorisasi, atau sertifikat klien TLS). |
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:
Deploy aplikasi backend dan frontend.
Buat dua gerbang masuk untuk mensimulasikan origin yang berbeda.
Siapkan aturan routing untuk kedua aplikasi.
Konfirmasi bahwa permintaan lintas asal gagal tanpa CORS.
Tambahkan
corsPolicydan verifikasi bahwa permintaan berhasil.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Namespace
defaultdanfootelah dibuat, dengan injeksi otomatis proxy sidecar diaktifkan untuk keduanya. Untuk detailnya, lihat Kelola namespace global
Langkah 1: Deploy aplikasi
Deploy aplikasi backend
Dapatkan file kubeconfig kluster Anda dan hubungkan dengan kubectl.
Buat file bernama
details.yaml:Deploy aplikasi di namespace
default:kubectl apply -f details.yaml -n default
Deploy aplikasi frontend
Buat file bernama
istio-cors-demo.yaml: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.
Masuk ke Konsol ASM. Di panel navigasi sebelah kiri, pilih Service Mesh > Mesh Management.
Pada halaman Mesh Management, klik nama instans ASM. Di panel navigasi sebelah kiri, pilih ASM Gateways > Ingress Gateway.
Pada halaman Ingress Gateway, klik Create.
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.Ulangi langkah 3 dan 4 untuk membuat gerbang masuk kedua bernama
ingressgateway2.
Langkah 3: Buat aturan routing
Rutekan traffic ke aplikasi backend
Buat gateway Istio yang mengaitkan layanan
detailsdengan gatewayingressgateway.Pada halaman detail instans ASM, pilih ASM Gateways > Gateway di panel navigasi sebelah kiri. Pada halaman Gateway, klik Create from YAML.
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
Buat VirtualService untuk backend.
Pada halaman detail instans ASM, pilih Traffic Management Center > VirtualService di panel navigasi sebelah kiri. Klik Create from YAML.
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
Verifikasi bahwa backend dapat diakses.
Dapatkan alamat IP gateway
ingressgateway. Untuk detailnya, lihat Buat ingress gateway.Buka
http://<ingressgateway-ip>/details/2di browser Anda.
Respons JSON menunjukkan bahwa backend dapat dijangkau.
Rutekan traffic ke aplikasi frontend
Buat gateway Istio yang mengaitkan layanan
istio-cors-demodengan gatewayingressgateway2.Pada halaman detail instans ASM, pilih ASM Gateways > Gateway di panel navigasi sebelah kiri. Klik Create from YAML.
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
Buat VirtualService untuk frontend.
Pada halaman detail instans ASM, pilih Traffic Management Center > VirtualService di panel navigasi sebelah kiri. Klik Create from YAML.
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
Dapatkan alamat IP gateway
ingressgateway2. Untuk detailnya, lihat Buat ingress gateway.Buka
http://<ingressgateway2-ip>di Google Chrome.Pada kolom URL di halaman tersebut, masukkan
http://<ingressgateway-ip>/details/2dan klik Send.
Buka Chrome DevTools (
F12, atau More tools > Developer tools). Konsol menampilkan error CORS. Frontend padaingressgateway2mengirim permintaan lintas asal ke backend padaingressgateway, dan belum ada kebijakan CORS yang diterapkan.
Langkah 4: Tambahkan kebijakan CORS
Masuk ke Konsol ASM. Di panel navigasi sebelah kiri, pilih Service Mesh > Mesh Management.
Klik nama instans ASM. Pilih Traffic Management Center > VirtualService di panel navigasi sebelah kiri.
Pada halaman VirtualService, temukan virtual service
bookinfodan klik YAML di kolom Actions.Pada dialog Edit, tambahkan blok
corsPolicyberikut ke bidanghttpdan klik OK: Ganti<ingressgateway2-ip>dengan alamat IP aktual gatewayingressgateway2.corsPolicy: allowCredentials: false allowMethods: - POST - GET allowOrigins: - prefix: 'http://<ingressgateway2-ip>' maxAge: 24h
Langkah 5: Verifikasi kebijakan CORS
Buka
http://<ingressgateway2-ip>di Google Chrome.Pada kolom URL, masukkan
http://<ingressgateway-ip>/details/2dan klik Send. Frontend kini berhasil mengambil data dari backend. Kebijakan CORS telah berlaku.
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, POSTPermintaan dikategorikan sebagai permintaan simple hanya jika semua kondisi berikut terpenuhi:
Metode HTTP adalah
GET,HEAD, atauPOST.Header
Content-Type(jika diatur) bernilaitext/plain,application/x-www-form-urlencoded, ataumultipart/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, danContent-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: 86400Jika 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
allowCredentialsbernilaitrue, browser menolak respons yang mengaturAccess-Control-Allow-Originke*. Sebagai gantinya, tentukan origin secara eksplisit.Batasi metode yang diizinkan. Izinkan hanya metode HTTP yang benar-benar dibutuhkan layanan Anda. Hindari menambahkan
DELETEatauPATCHkecuali benar-benar diperlukan.Atur
maxAgeyang wajar. Menyimpan cache respons preflight mengurangi latensi untuk permintaan lintas asal berulang, tetapi durasi cache yang terlalu lama dapat menunda penerapan perubahan kebijakan. Nilai antara1hdan24hcocok untuk sebagian besar kasus penggunaan.Lebih baik gunakan pencocokan
exactatauprefixdaripadaregex. Pola regex yang terlalu luas dapat secara tidak sengaja mengizinkan origin yang tidak tepercaya. Uji pola regex sebelum menerapkannya di lingkungan produksi.