API Authentication Patterns — Security

Pola Autentikasi API Memilih pola autentikasi yang tepat untuk API sangat penting. Setiap pola memiliki kelebihan dan kekurangan tergantung pada use case. 1…

Autentikasi API adalah cara server mengenali siapa yang memanggil, di setiap request, karena HTTP gak ingat request sebelumnya. Bayangin gedung kantor dengan empat cara masuk: vendor punya kartu akses permanen (API key), tamu dapat badge tamu yang berlaku sampai jam lima sore dan siapa pun yang memegangnya boleh masuk (Bearer token), karyawan dicatat di buku resepsionis yang bisa dicoret kapan saja (session cookie), dan kurir dokumen penting membawa surat bersegel yang membuktikan pengirimnya dan bahwa isinya belum dibuka (HMAC).

🧪 Tebakan cepat: kamu mengirim API key lewat URL, ?api_key=sk_live_abc123def456, di atas HTTPS. HTTPS mengenkripsi URL selama di jalan. Jadi aman? Tebak dulu, jawabannya ada di bagian "Jangan taruh kredensial di URL".

Empat pola, satu request

Di Lab, request yang sama, POST /api/orders berisi {"item":"kopi","qty":2}, dikirim dengan empat pola. Bedanya ada di tempat kredensial dibawa dan apa yang disimpan server.

Pola Dibawa di Server menyimpan Bisa dicabut seketika? Cocok untuk
API key header X-API-Key daftar key (hash-nya) ya, hapus key-nya server ke server
Bearer token header Authorization: Bearer ... gak ada (stateless) gak, tunggu sampai kedaluwarsa SPA, mobile app
Session cookie header Cookie, dikirim browser otomatis session store ya, hapus session-nya web di satu domain
HMAC signature header X-Timestamp dan X-Signature secret bersama ya, ganti secret webhook, API pembayaran

Kredensial artinya bukti identitas yang dikirim: key, token, cookie, atau tanda tangan.

API key

POST /api/orders HTTP/1.1
Host: api.situsmu.com
X-API-Key: sk_live_abc123def456
Content-Type: application/json

{"item":"kopi","qty":2}

Bearer token

POST /api/orders HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImlhdCI6MTc5MTQyOTMwMCwiZXhwIjoxNzkxNDMwMjAwfQ.QZgI2cMuNVBfqkk3a05RJFbi-_YlqbS5QmREALijrnA

Lewat dari pukul 10.30, request yang sama dijawab:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", error_description="The access token expired"

Session cookie

POST /api/login        ->  Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax
POST /api/orders       ->  Cookie: session=abc123   (dikirim browser otomatis)

HMAC signature

Client dan server sama-sama tahu satu secret bersama, rahasia-toko-123, yang gak pernah dikirim. Client menandatangani isi request:

const timestamp = '1791429300'
const body = '{"item":"kopi","qty":2}'
const payload = `POST\n/api/orders\n${timestamp}\n${body}`
const signature = await hmacSha256Hex('rahasia-toko-123', payload)
// 348fdaefa266632ee8f24a88c7061eaddd6f999893acf06bd2bdec8d32f07b59

Session-based vs token-based

Session-based menyimpan state di server dan mengirim session ID lewat cookie: mudah dicabut, cocok untuk web biasa di satu domain, tapi butuh session store yang bisa diakses semua server. Token-based (JWT, PASETO) menyimpan data di token itu sendiri: stateless, gampang dipakai banyak server dan lintas domain, gak bergantung pada cookie. Untuk API yang dipakai mobile app, pilih token-based: aplikasi mobile gak berjalan di browser, jadi aturan cookie browser gak banyak membantu, sedangkan token tinggal dikirim di header Authorization ke server mana pun. Kekurangannya, token sulit dicabut sebelum exp, jadi buat umur access token pendek.

Jangan taruh kredensial di URL

HTTPS memang mengenkripsi URL di jalan, tapi URL dicatat di banyak tempat setelah sampai: access log server, riwayat browser, log proxy, dan tool analytics. Ini baris log server yang sama di Lab, dengan key di URL:

203.0.113.7 - - [08/Oct/2026:10:15:00 +0700] "POST /api/orders?api_key=sk_live_abc123def456 HTTP/1.1" 201 32 "-" "curl/8.7.1"

Siapa pun yang bisa membaca log itu sekarang memegang key-nya. Jadi gak aman. Itu jawaban tebakannya. Dengan key di header X-API-Key, barisnya cuma "POST /api/orders HTTP/1.1". API key memang kadang dikirim lewat query parameter, tapi header selalu lebih baik.

⚠️ Jebakan yang sering ketemu

TL;DR: Server harus mengenali pemanggil di tiap request. API key adalah key unik per klien, dikirim di header (bisa lewat query parameter, tapi jangan), cocok untuk server ke server. Bearer token dikirim di header Authorization: Bearer ..., stateless, berumur pendek dengan refresh token, dan lewat exp dijawab 401 dengan WWW-Authenticate: Bearer error="invalid_token". Session cookie disimpan di session store, bisa dicabut seketika, tapi butuh perlindungan CSRF. HMAC menandatangani method, path, timestamp, dan body dengan secret bersama, jadi isi yang diubah langsung ketahuan. Untuk mobile app, pilih token-based. Selalu pakai HTTPS, dan jangan pernah taruh kredensial di URL karena tercatat di log.

Yang akan kamu pelajari