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}
- API key adalah string unik per klien (aplikasi, bukan orang). Server mencocokkannya dengan daftar key, lalu tahu "ini aplikasi kasir".
- Server sebaiknya menyimpan hash dari key, bukan key aslinya, sama seperti password.
- Kekurangannya: key berlaku terus sampai dihapus, dan gak menunjuk ke user tertentu. Jangan pernah taruh di kode frontend, karena siapa pun bisa membacanya dari DevTools.
Bearer token
POST /api/orders HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImlhdCI6MTc5MTQyOTMwMCwiZXhwIjoxNzkxNDMwMjAwfQ.QZgI2cMuNVBfqkk3a05RJFbi-_YlqbS5QmREALijrnA
- Skema autentikasi yang mengirim token lewat header
Authorizationdisebut Bearer. Artinya "siapa pun yang membawa token ini". Jadi token yang dicuri bisa langsung dipakai pencurinya. - Alurnya: user login, server memberi access token (umurnya pendek, di sini 15 menit) dan refresh token (umurnya panjang). Access token dikirim di tiap request. Kalau sudah kedaluwarsa, client memakai refresh token untuk minta access token baru.
- Token ini JWT: isinya
{"sub":"42","iat":1791429300,"exp":1791430200}, yaitu user 42, dibuat pukul 10.15, kedaluwarsa pukul 10.30. Server cukup mengecek tanda tangan danexp, tanpa bertanya ke database.
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)
- Server menyimpan
abc123 -> user 42di session store (database atau Redis). Tiap request, server mencari session itu. - Logout atau "keluar dari semua perangkat" tinggal menghapus
abc123. Request berikutnya langsung dijawab401, walaupun browser masih mengirim cookie yang sama. - Karena browser mengirim cookie otomatis, situs lain bisa memancing browser korban mengirim request. Jadi pola ini butuh perlindungan CSRF (
SameSitedan token CSRF, dibahas di pelajaran CSRF).
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
- HMAC adalah hash yang dicampur secret. Tanpa secret, gak ada yang bisa membuat tanda tangan yang cocok.
- Server menghitung ulang dari method, path, timestamp, dan body yang diterima, lalu membandingkan. Kalau body diubah di jalan jadi
"qty":200, hasil hitungan server jadi79e47b46c97e...8b8f92, gak sama, jadi401. X-Timestampdicek juga: request yang lebih tua dari 5 menit ditolak, supaya request lama gak bisa dikirim ulang.- Paling kuat, tapi paling rumit. Biasa dipakai untuk webhook dan API pembayaran.
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
- Kredensial di URL. Masuk log, riwayat browser, dan header
Referer. Taruh di header. - API key di kode frontend. Semua yang dikirim ke browser bisa dibaca. API key untuk server ke server saja.
- Access token berumur panjang. Token Bearer yang dicuri berlaku sampai
exp. Buat pendek (misalnya 15 menit) dan pakai refresh token. - Session cookie tanpa perlindungan CSRF. Browser mengirim cookie otomatis, termasuk ke request yang dipancing situs lain.
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.