Bearer Token & JWT: Standar Login API Modern
Cara kerja bearer token, anatomi JWT (header.payload.signature), dan praktik penyimpanan yang aman.
Kartu akses hotel yang kedaluwarsa sendiri
Check-in hotel, kamu dapat kartu akses kamar yang mati otomatis saat checkout. Tidak perlu dikembalikan, tidak perlu dimatikan manual. JWT (JSON Web Token) bekerja mirip: token yang membawa identitasmu dan kedaluwarsa sendiri, dipakai lewat skema Bearer di header Authorization.
Kenapa token mengalahkan session
Session klasik menyimpan data login di server, sehingga setiap request harus mengecek database. JWT membalik logikanya: semua info penting (id user, peran, waktu kedaluwarsa) ditulis DI DALAM token dan ditandatangani secara kriptografis. Server cukup memverifikasi tanda tangan, tanpa menyimpan apa pun. Hasilnya: stateless, mudah diskalakan, dan cocok untuk API yang dipakai banyak klien (web, mobile, pihak ketiga).
Contoh 1: anatomi JWT
Token JWT punya tiga bagian dipisah titik:
eyJhbGciOiJIUzI1NiJ9.eyJpZCI6NDIsInJvbGUiOiJhZG1pbiJ9.tanda-tangan
- Header: algoritma tanda tangan.
- Payload: data, misalnya
{"id": 42, "role": "admin", "exp": 1728384000}. Perhatian: payload hanya di-encode, TIDAK dienkripsi, jadi jangan taruh data rahasia di sini. - Signature: tanda tangan yang membuktikan token tidak dipalsukan. Hanya server pemilik secret key yang bisa membuatnya.
Contoh 2: alur login sampai request
Login dulu untuk mendapatkan token:
POST /api/login HTTP/1.1
Host: toko.contoh.id
Content-Type: application/json
{"email": "[email protected]", "password": "rahasia"}HTTP/1.1 200 OK
{"token": "eyJhbGciOi..."}Lalu pakai token di setiap request:
const response = await fetch("https://toko.contoh.id/api/profil", {
headers: { "Authorization": "Bearer " + token }
});Kata Bearer berarti "siapa pun yang membawa token ini dianggap pemiliknya." Makanya token harus dijaga seperti password.
Kesalahan umum
Salah: menyimpan JWT di localStorage untuk aplikasi sensitif. Rentan dicuri lewat XSS. Yang benar: untuk keamanan maksimal pakai httpOnly cookie; localStorage hanya untuk kasus risiko rendah.
Salah: menaruh data rahasia di payload. Payload bisa di-decode siapa pun. Yang benar: hanya id dan peran, bukan password atau data pribadi sensitif.
Salah: membuat token tanpa kedaluwarsa. Token abadi yang bocor memberi akses selamanya. Yang benar: access token berumur pendek (15 menit - 1 jam) plus refresh token untuk memperbarui.
Salah: tidak menangani 401 dengan refresh. Token kedaluwarsa lalu aplikasi logout paksa padahal bisa diperbarui diam-diam. Yang benar: saat 401, coba refresh token dulu, baru anggap sesi berakhir.
Struktur payload yang baik
Contoh payload JWT yang dirancang benar:
{
"sub": "user_42",
"role": "kasir",
"iat": 1728384000,
"exp": 1728387600
}sub(subject): siapa pemilik token, pakai ID bukan email (email bisa berubah).role: untuk otorisasi cepat tanpa query database.iat/exp: kapan dibuat dan kedaluwarsa (wajib ada).
Yang TIDAK boleh ada: password, nomor KTP, atau data sensitif lain. Ingat: payload hanya di-encode base64, siapa pun bisa membacanya. Token yang baik itu minimalis.
Catatan teknis: Verifikasi JWT selalu di sisi server dengan secret key yang tidak pernah dibagikan. Jangan pernah memverifikasi token hanya di frontend: itu seperti memeriksa KTP dengan melihat fotokopinya saja.
Tantangan
Bedah JWT asli
Ambil contoh JWT ini (token dummy untuk latihan):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NywibmFtYSI6IkJ1ZGkiLCJyb2xlIjoic2lzd2EiLCJleHAiOjE4MDAwMDAwMDB9.dummy
- Tulis fungsi
bacaPayload(token)yang mengembalikan object payload-nya. - Dari payload, jawab: siapa nama usernya, apa role-nya, dan kapan token ini kedaluwarsa (convert
expke tanggal dengannew Date(exp * 1000))? - Jelaskan kenapa payload JWT tidak boleh berisi data rahasia seperti password.
<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Halo JS</h1> <p>Buka console preview untuk melihat output.</p> <script src="index.js"></script> </body> </html>