Anda sedang melihat dokumentasi Apigee Edge.
Lihat dokumentasi Apigee X.
CORS (Cross-origin resource sharing) adalah mekanisme standar yang memungkinkan panggilan JavaScript XMLHttpRequest (XHR) yang dijalankan di halaman web untuk berinteraksi dengan resource dari domain non-origin. CORS adalah solusi yang umum diterapkan untuk "kebijakan asal yang sama" yang diterapkan oleh semua browser. Misalnya, jika Anda melakukan panggilan XHR ke Twitter API dari kode JavaScript yang dieksekusi di browser, panggilan akan gagal. Ini karena domain yang menayangkan halaman ke browser Anda tidak sama dengan domain yang menayangkan Twitter API. CORS memberikan solusi untuk masalah ini dengan memungkinkan server untuk "ikut serta" jika ingin menyediakan berbagi resource lintas asal.
Video: Tonton video singkat untuk mempelajari cara mengaktifkan CORS pada proxy API.
Kasus penggunaan standar untuk CORS
Kode JQuery berikut memanggil layanan target fiktif. Jika dieksekusi dari dalam konteks browser (halaman web), panggilan akan gagal karena kebijakan asal yang sama:
<script> var url = "http://service.example.com"; $(document).ready(function(){ $("button").click(function(){ $.ajax({ type:"GET", url:url, async:true, dataType: "json", success: function(json) { // Parse the response. // Do other things. }, error: function(xhr, status, err) { // This is where we end up! } }); }); }); </script>
Salah satu solusi untuk masalah ini adalah dengan membuat proxy Apigee API yang memanggil API layanan di backend. Ingat bahwa Edge berada di antara klien (dalam hal ini browser) dan API backend (layanan). Karena proxy API dijalankan di server, bukan di browser, proxy berhasil memanggil layanan. Kemudian, Anda hanya perlu melampirkan header CORS ke respons TargetEndpoint. Selama browser mendukung CORS, header ini akan memberi tahu browser bahwa browser tidak perlu "melonggarkan" kebijakan asal yang sama, sehingga panggilan API lintas asal dapat berhasil.
Setelah proxy dengan dukungan CORS dibuat, Anda dapat memanggil URL proxy API, bukan layanan backend dalam kode sisi klien Anda. Contoh:
<script> var url = "http://myorg-test.apigee.net/v1/example"; $(document).ready(function(){ $("button").click(function(){ $.ajax({ type:"GET", url:url, async:true, dataType: "json", success: function(json) { // Parse the response. // Do other things. }, error: function(xhr, status, err) { // This time, we do not end up here! } }); }); }); </script>
Melampirkan kebijakan Tambahkan CORS ke proxy API baru
Anda dapat menambahkan dukungan CORS ke proxy API dengan melampirkan kebijakan "Tambahkan CORS" ke proxy API saat membuatnya. Untuk menambahkan kebijakan ini, centang kotak Add CORS header di halaman Keamanan pada wizard Build a Proxy.
Jika Anda mencentang kotak ini, kebijakan yang disebut Add CORS akan otomatis ditambahkan ke sistem dan dilampirkan ke pra-alur respons TargetEndpoint, seperti ditunjukkan dalam gambar berikut:
Kebijakan Add CORS diimplementasikan sebagai kebijakanassignMessage, yang menambahkan header yang sesuai ke respons. Pada dasarnya, header memberi tahu browser tempat asal resource akan dibagikan, metode mana yang diterima, dan sebagainya. Anda dapat membaca selengkapnya tentang header CORS ini di Rekomendasi W3C Cross-Origin Resource Sharing.
Anda harus mengubah kebijakan, sebagai berikut:
- Tambahkan header
content-type
danauthorization
(diperlukan untuk mendukung autentikasi dasar atau OAuth2) ke headerAccess-Control-Allow-Headers
, seperti yang ditunjukkan dalam cuplikan kode di bawah ini. - Untuk autentikasi OAuth2, Anda mungkin perlu mengambil langkah-langkah untuk memperbaiki perilaku yang tidak sesuai dengan RFC.
- Sebaiknya gunakan
<Set>
untuk menyetel header CORS, bukan<Add>
, seperti yang ditunjukkan dalam kutipan di bawah. Saat menggunakan<Add>
, jika headerAccess-Control-Allow-Origin
sudah ada, Anda akan menerima error berikut:The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
Untuk informasi selengkapnya, lihat Error CORS : header berisi beberapa nilai '*, *', tetapi hanya satu yang diizinkan.
<AssignMessage async="false" continueOnError="false" enabled="true" name="add-cors"> <DisplayName>Add CORS</DisplayName> <FaultRules/> <Properties/> <Set> <Headers> <Header name="Access-Control-Allow-Origin">{request.header.origin}</Header> <Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type, authorization</Header> <Header name="Access-Control-Max-Age">3628800</Header> <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header> </Headers> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="response"/> </AssignMessage>
Menambahkan header CORS ke proxy yang sudah ada
Anda perlu membuat kebijakan Tetapkan Pesan Baru secara manual dan menyalin kode untuk kebijakan Tambahkan CORS yang tercantum di bagian sebelumnya. Kemudian, lampirkan kebijakan ke pra-respons respons Endpoint API proxy. Anda dapat mengubah nilai header sesuai kebutuhan. Untuk informasi selengkapnya tentang cara membuat dan melampirkan kebijakan, lihat Apa itu kebijakan?.
Menangani permintaan preflight CORS
Preflight CORS mengacu pada pengiriman permintaan ke server untuk memverifikasi apakah server mendukung CORS. Respons preflight biasanya mencakup asal yang akan menerima permintaan CORS, daftar metode HTTP yang didukung untuk permintaan CORS, header yang dapat digunakan sebagai bagian dari permintaan resource, respons preflight waktu maksimum yang akan disimpan dalam cache, dan lainnya. Jika layanan tidak menunjukkan dukungan CORS atau tidak ingin menerima permintaan lintas asal dari asal klien, kebijakan lintas asal browser akan diterapkan dan permintaan lintas domain apa pun yang dibuat dari klien untuk berinteraksi dengan resource yang dihosting di server tersebut akan gagal.
Biasanya, permintaan preflight CORS dibuat dengan metode OPSI HTTP. Saat server yang mendukung CORS menerima permintaan OPSI, server tersebut akan menampilkan serangkaian header CORS ke klien yang menunjukkan level dukungan CORS. Sebagai hasil dari handshake ini, klien tahu apa yang diperbolehkan untuk diminta dari domain non-origin.
Untuk mengetahui informasi selengkapnya tentang preflight, lihat Rekomendasi W3C Cross-Origin Resource Sharing. Selain itu, ada banyak blog dan artikel di CORS yang dapat Anda rujuk.
Apigee tidak menyertakan solusi preflight CORS, tetapi dapat diterapkan, seperti yang dijelaskan di bagian ini. Tujuannya adalah agar proxy dapat mengevaluasi permintaan OPSI dalam alur kondisional. Proxy kemudian dapat mengirimkan respons yang sesuai kembali ke klien.
Mari kita lihat alur contoh, lalu diskusikan bagian-bagian yang menangani permintaan preflight:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ProxyEndpoint name="default"> <Description/> <Flows> <Flow name="OptionsPreFlight"> <Request/> <Response> <Step> <Name>add-cors</Name> </Step> </Response> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </Flow> </Flows> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <HTTPProxyConnection> <BasePath>/v1/cnc</BasePath> <VirtualHost>default</VirtualHost> <VirtualHost>secure</VirtualHost> </HTTPProxyConnection> <RouteRule name="NoRoute"> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </RouteRule> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> </ProxyEndpoint>
Bagian utama dari ProxyEndpoint ini adalah sebagai berikut:
- RouteRule dibuat ke target NULL dengan kondisi untuk permintaan OPTIONS. Perhatikan bahwa tidak ada TargetEndpoint yang ditentukan. Jika permintaan OPTIONS diterima dan header permintaan Origin dan Access-Control-Request bukan null, proxy akan segera menampilkan header CORS sebagai respons terhadap klien (dengan mengabaikan target "backend" default yang sebenarnya).
Untuk detail tentang kondisi alur dan RouteRule, lihat Kondisi dengan variabel flow.
<RouteRule name="NoRoute"> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </RouteRule>
- Alur OptionsPreFlight dibuat yang menambahkan kebijakan Add CORS, yang berisi header
CORS, ke alur jika permintaan OPTIONS diterima dan header permintaan Origin dan
Access-Control-Request-Method bukan null.
<Flow name="OptionsPreFlight"> <Request/> <Response> <Step> <Name>add-cors</Name> </Step> </Response> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </Flow>
Menggunakan solusi CORS sampel
Contoh solusi CORS, yang diterapkan sebagai alur bersama, tersedia di GitHub. Impor paket alur bersama ke lingkungan Anda dan lampirkan menggunakan hook alur atau langsung ke alur proxy API. Untuk mengetahui detailnya, lihat file CORS-Shared-FLow README yang disediakan dengan contoh.