Best practices untuk implementasi authentication yang aman — dari JWT hingga OAuth
Panduan ringkas tapi komprehensif: desain, implementasi, dan operational security untuk sistem autentikasi modern.
Ringkasan
Autentikasi aman tidak hanya soal memilih JWT atau OAuth — melainkan kombinasi desain protokol, manajemen kunci, proteksi terhadap XSS/CSRF, penggunaan TLS, & lifecycle token (expiration, revocation, rotation). Dokumen ini merangkum praktik terbaik dan trade-off untuk skenario web, mobile, dan API.
Sumber utama: OWASP Authentication & Authorization Cheat Sheets, NIST SP 800-63B, OAuth Security Best Current Practice, serta panduan JWT/Auth0/industry. :contentReference[oaicite:0]{index=0}
Daftar isi
Prinsip umum (passwords, MFA, TLS)
Sessions vs Tokens (JWT) — kapan pakai apa
JWT: praktik aman (signing, claims, storage, revocation)
OAuth: flow yang disarankan (Auth Code + PKCE, refresh tokens)
Gunakan TLS (HTTPS) selalu — jangan pernah kirim credential/token lewat HTTP plain. (TLS wajib untuk semua transport token dan credentials).
Password & memorizable secrets — ikuti panduan kekuatan password. Lebih baik pakai passphrases, bcrypt/argon2 untuk hashing, dan jangan pangkas entropy. NIST SP 800-63 memberi panduan tentang strength & blacklist kata sandi. :contentReference[oaicite:1]{index=1}
MFA wajib di titik risiko tinggi — gunakan OTP berbasis TOTP/Push/Hardware (AAL2/AAL3). NIST merekomendasikan AAL2+ untuk layanan sensitif. :contentReference[oaicite:2]{index=2}
Least privilege & proper authorization — autentikasi bukan akhir: otorisasi harus eksplisit dan diuji. Gunakan prinsip role-based atau attribute-based authorization, per OWASP. :contentReference[oaicite:3]{index=3}
2. Sessions vs Tokens (stateful vs stateless)
Pilihan antara session cookies (server-side sessions) dan token (mis. JWT) bergantung pada kebutuhan:
Session cookies (server-side) lebih mudah di-revoke karena server menyimpan state; cocok untuk aplikasi web tradisional.
JWT / stateless tokens berguna untuk scale/distributed systems dan API: token berisi claims dan diverifikasi tanpa lookup server. Namun perlu strategi revocation/refresh karena sifatnya “self-contained”.
Tip: untuk web apps modern, kombinasi yang sering dipakai adalah short-lived access token + HttpOnly Secure refresh cookie (server rotates refresh tokens) untuk keseimbangan keamanan & skalabilitas. Sumber praktik token: Auth0 & industry best practices. :contentReference[oaicite:4]{index=4}
3. JWT — praktik aman
a) Gunakan JWT untuk tujuan tepat
JWT bagus untuk membawa claims yang perlu diverifikasi tanpa lookup. Jangan gunakan JWT untuk menyimpan data sensitif (PII) tanpa enkripsi.
b) Pilih algoritma signing yang kuat
Prefer RS256 (asymmetric) atau ES256 (ECDSA) untuk token yang diverifikasi oleh banyak pihak. HS256 (HMAC) cocok di lingkungan yang men-share secret dan trusted, tapi hati-hati manajemen kuncinya.
Jangan terima "alg: none" dan validasi alg di server. Selalu verifikasi signature. Dokumentasi JWT dan panduan praktis menekankan ini. :contentReference[oaicite:5]{index=5}
c) Claims: minimal & eksplisit
Gunakan claim standar (iss, sub, aud, exp, iat) dan hindari claim berlebih.
Set exp pendek untuk access token (misal: menit-jam), gunakan refresh token untuk durasi lebih panjang.
d) Penyimpanan token di client
Penyimpanan token adalah sumber kesalahan terbesar:
Web browser: simpan access token di memori (JS variable) atau gunakan cookie HttpOnly; Secure; SameSite=Strict/Lax. Hindari menyimpan access token di localStorage jika target web rentan XSS. Cookie HttpOnly + SameSite + CSRF token (untuk non-idempotent endpoints) adalah pola yang aman. :contentReference[oaicite:6]{index=6}
Mobile/Native: gunakan secure storage (Keychain di iOS, Keystore di Android) dan implement PKCE untuk flow OAuth. :contentReference[oaicite:7]{index=7}
e) Revocation & rotation
Karena JWT stateless, revocation harus di-handle: gunakan short-lived access token + refresh token yang stateful (server keeps revocation list or rotating identifier).
Implement token identifier (jti) dan mekanisme blacklist/denylist jika perlu revoke segera.
f) Protect against replay & misuse
Gunakan TLS, cek aud & iss, verifikasi exp & nbf.
4. OAuth — best practices & flows
OAuth adalah framework otorisasi (bukan autentikasi—walaupun sering dipakai untuk login). Gunakan flow yang sesuai:
a) Authorization Code + PKCE (recommended)
Untuk semua aplikasi publik (browser SPAs, mobile), gunakan Authorization Code Flow with PKCE (Proof Key for Code Exchange). Ini mitigasi code interception dan adalah praktik standar terbaru (OAuth 2.1 / Security BCP / RFCs). :contentReference[oaicite:8]{index=8}
b) Hindari Implicit Flow
Implicit flow (token langsung di URL fragment) sudah dianggap usang/unsafe. Gunakan authorization code + PKCE sebagai gantinya. :contentReference[oaicite:9]{index=9}
c) Refresh token handling
Refresh token sebaiknya tidak dipaparkan ke browser JS; gunakan HttpOnly cookie atau backend-for-frontend (BFF) pattern.
Rotate refresh token tiap kali digunakan — deteksi replay token untuk potensi compromise dan segera revoke. OAuth security draft & provider best practices merekomendasikan rotating refresh tokens. :contentReference[oaicite:10]{index=10}
d) Client authentication & secrets
Client secrets tidak boleh disimpan di aplikasi publik (SPA, mobile). Gunakan PKCE dan treat clients as public unless server-side confidential client.
5. Proteksi XSS, CSRF, dan header security
XSS: cegah XSS karena XSS -> pencurian token (jika token diakses oleh JS). Validasi & escape output, Content Security Policy (CSP), dan sanitasi input.
CSRF: Jika pakai cookies (session atau refresh cookie), pastikan proteksi CSRF (Double Submit Cookie, SameSite, atau CSRF token).
Security headers: set Strict-Transport-Security, Referrer-Policy, Content-Security-Policy, X-Frame-Options.
Prinsip: jika token dapat diakses oleh JavaScript, asumsi bahwa XSS bisa mengancam token itu — minimalkan surface attack. Sumber OWASP & Auth0. :contentReference[oaicite:11]{index=11}
6. Implementasi praktis & contoh
a) Contoh: akses token pendek + refresh cookie (pseudocode)
// /auth/refresh
read cookie refresh
if not found -> 401
validate refreshId in DB and not revoked
if valid:
rotateRefresh = generateRandomId()
update DB (replace old refreshId with new)
issue new accessToken (short-lived)
set new refresh cookie
return accessToken
else revoke session -> 401
✅ JWT: short exp, alg whitelisting, signature verified
✅ Refresh tokens: rotate & store server-side
✅ CSRF/XSS mitigations
✅ Key rotation policy
✅ Logging & alerting untuk auth anomalies
✅ Threat model & documented incident response
9. FAQ singkat
Q: Apakah JWT "berbahaya"?
A: Bukan intrinsically; risiko muncul jika JWT disalahgunakan — mis. lifetime terlalu panjang, storage di localStorage tanpa proteksi XSS, atau tidak ada mekanisme revocation. Gunakan best practices: short-lived tokens + secure refresh flow + algoritma dan signature yang benar. :contentReference[oaicite:12]{index=12}