Header udah dipasang, dokumentasi udah diikutin, browser tetap nolak. Enam sebab berikut nyakup hampir semuanya, diurutin dari yang paling sering.
1. Dipasang di sisi yang salah
Ini yang ngabisin jam-jam pertama.
CORS dipasang di server yang NGELAYANIN API, bukan di situs yang manggil.
Dia itu izin yang dikasih penyedia data ke pemanggilnya. Masang di sisi pemanggil nggak ngefek apa-apa.
Kalau situs Anda manggil API punya orang lain terus ditolak, nggak ada yang bisa Anda pasang di sisi Anda buat benerin. Yang harus berubah ada di sisi mereka. Atau panggilannya dipindah ke server Anda sendiri, yang nggak keiket aturan CORS sama sekali.
2. Origin-nya nggak cocok persis
Browser bandingin Origin persis, termasuk skema sama port:
https://app.contoh.idbeda darihttp://app.contoh.idhttps://app.contoh.idbeda darihttps://app.contoh.id/(ada garis miring)https://app.contoh.idbeda darihttps://app.contoh.id:443, walaupun portnya sama
Cek yang beneran dikirim: DevTools, tab Network, pilih requestnya, lihat header Origin di Request Headers.
3. Vary: Origin nggak dipasang
Kalau beberapa origin diizinin, server nyocokin Origin yang masuk terus mantulin yang cocok. Tanpa header Vary: Origin, cache di depan server bisa nyimpen jawaban buat satu origin terus nyajiin ke origin lain.
Gejalanya khas dan nyiksa: penolakan yang datang dan pergi tanpa pola, cuma di sebagian pengunjung, dan ilang pas Anda cek sendiri.
4. Preflight nggak dijawab
Buat request selain GET sama POST sederhana, browser ngirim OPTIONS dulu buat nanya izin.
Banyak framework nolak metode OPTIONS dengan 405, dan requestnya berhenti di situ, sebelum request beneran pernah dikirim.
Jawab di tingkat server web, sebelum nyentuh aplikasi:
if ($request_method = OPTIONS) {
return 204;
}5. Bintang digabung sama kredensial
Access-Control-Allow-Origin: * nggak boleh digabung sama Allow-Credentials: true. Browser nolak.
Yang bahaya bukan penolakannya, tapi cara orang ngakalinnya: mantulin balik apa pun isi header Origin.
Itu artinya tiap situs di internet jadi origin yang diizinin, lengkap sama cookie session pengguna. Siapa pun bisa bikin halaman yang baca data akun pengunjung Anda, cukup nunggu mereka buka.
Yang bener: cocokin sama whitelist, terus pantulin yang ada di daftar doang.
Generator CORS nolak ngasilin pola yang bahaya, sekalian nyusun pencocokan whitelist buat Nginx, Apache, dan PHP.
6. Cookie-nya nggak ikut kekirim
Kalau pakai cookie, dua hal harus bener bareng:
- Sisi client:
fetch(url, { credentials: "include" }) - Cookie session-nya:
SameSite=None; Secure
Tanpa yang pertama, header servernya nggak ada gunanya. Tanpa yang kedua, browser modern buang cookie-nya diam-diam.
Gejalanya sama di dua-duanya: request berhasil, tapi penggunanya selalu dianggap belum login.
Yang perlu diluruskan: CORS bukan pengaman
CORS cuma ngatur apa yang boleh dilakuin JavaScript di browser orang lain. curl, Postman, dan program apa pun ngabaikan sepenuhnya. Mereka nggak pernah nanya izin.
Makanya API yang perlu dilindungi tetap butuh autentikasi. Ngandelin CORS sebagai pembatas akses itu salah paham yang keliatan berhasil sampai ada yang buka Postman.
Satu lagi: waktu browser ngeblokir jawaban gara-gara CORS, requestnya sendiri tetap nyampe ke server dan tetap diproses. Jadi request yang ngubah data tetap kejadian walau jawabannya diblokir.