API, Autentikasi, dan Keamanan · 7/7
CORS dan security header
Error yang pasti dialami setiap developer, apa yang sebenarnya dilindunginya, dan cara mengaturnya dengan benar.
Baca 25 menit
Setelah pelajaran ini kamu bisa
- Menjelaskan apa yang sebenarnya dilindungi CORS
- Membaca error CORS dan tahu itu masalah siapa
- Mengonfigurasi CORS tanpa membuka semuanya
- Menyebutkan security header yang layak diatur
Setiap developer pernah menemui error CORS dan sebagian besar menyimpulkan itu penghalang yang harus dihilangkan. Ia adalah perlindungan browser, dan memahami apa yang dilindunginya langsung memberitahumu apakah kamu sedang memperbaikinya atau justru melumpuhkannya.
Aturan di bawahnya adalah same-origin policy: JavaScript di satu origin tidak bisa membaca response dari origin lain. Origin adalah scheme + host + port — ketiganya. Tanpa aturan ini, situs apa pun yang kamu buka bisa membaca webmail-mu di latar belakang memakai cookie-mu.
Mana di antara ini yang origin-nya sama? Ketiga bagiannya harus cocok.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Bagaimana CORS memberi pengecualian
CORS adalah server yang menyatakan "origin ini boleh membaca response saya". Ia diberikan lewat response header, dan browser yang menegakkannya. Yang penting: hanya server yang bisa memberikannya. Tidak ada perubahan di frontend-mu yang bisa memperbaiki error CORS.
// In a Route Handler, on the API side:
export async function GET(request: Request) {
const origin = request.headers.get("origin");
const allowed = ["https://app.example.com", "https://staging.example.com"];
const headers = new Headers();
if (origin && allowed.includes(origin)) {
headers.set("Access-Control-Allow-Origin", origin); // echo the one origin
headers.set("Access-Control-Allow-Credentials", "true");
headers.set("Vary", "Origin"); // so caches do not mix them up
}
return Response.json(await getVenues(), { headers });
}
// A preflight OPTIONS request must be answered too.
export async function OPTIONS(request: Request) {
return new Response(null, {
status: 204,
headers: {
"Access-Control-Allow-Origin": "https://app.example.com",
"Access-Control-Allow-Methods": "GET, POST, DELETE",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Max-Age": "86400",
},
});
}OPTIONS otomatis yang dikirim browser lebih dulu, untuk apa pun di luar GET sederhana atau form POST. Kalau ia tidak dijawab, request sebenarnya tidak akan pernah terjadi.Keputusan preflight, diimplementasikan. Perhatikan kombinasi yang ditolak langsung oleh browser.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Security header
| Header | Fungsinya |
|---|---|
Content-Security-Policy | Membatasi dari mana script boleh dimuat — pertahanan XSS terkuat |
Strict-Transport-Security | Memaksa HTTPS untuk kunjungan berikutnya |
X-Content-Type-Options: nosniff | Mencegah browser menebak-nebak type sebuah file |
X-Frame-Options: DENY | Mencegah situsmu dibingkai untuk clickjacking |
Referrer-Policy | Membatasi apa yang kamu bocorkan di header Referer |
Tugas praktik
Buka halaman mana pun di proyek ini di DevTools → Network, klik request dokumennya, lalu baca Response Header-nya. Catat mana dari tabel di atas yang ada dan mana yang tidak. Lalu lakukan pemeriksaan yang sama di situs sebuah bank dan bandingkan — kamu akan melihat daftar yang jauh lebih panjang, termasuk sebuah CSP.
Hasil yang diharapkan
Proyek ini hanya mengatur sedikit di antaranya — sebuah temuan nyata, dan kontribusi pertama yang wajar.