Lompat ke konten
Kembali ke modul

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.

Coba sendiri

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.

ts
// 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",
    },
  });
}
Preflight adalah request 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.
Coba sendiri

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

HeaderFungsinya
Content-Security-PolicyMembatasi dari mana script boleh dimuat — pertahanan XSS terkuat
Strict-Transport-SecurityMemaksa HTTPS untuk kunjungan berikutnya
X-Content-Type-Options: nosniffMencegah browser menebak-nebak type sebuah file
X-Frame-Options: DENYMencegah situsmu dibingkai untuk clickjacking
Referrer-PolicyMembatasi 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.