Pelajari apa itu JWT (JSON Web Token), bagaimana tiga bagiannya bekerja, di mana digunakan, dan tip keamanan utama untuk menghindari kesalahan token umum.

Sebuah JWT (JSON Web Token) adalah string ringkas yang aman untuk URL yang merepresentasikan sekumpulan informasi (biasanya tentang pengguna atau sesi) dengan cara yang dapat dikirim antar sistem. Anda sering melihatnya sebagai nilai panjang yang dimulai dengan sesuatu seperti eyJ..., dikirim dalam header HTTP seperti Authorization: Bearer <token>.
Login tradisional sering mengandalkan session server: setelah Anda masuk, server menyimpan data session dan memberi browser cookie dengan ID session. Setiap permintaan menyertakan cookie itu, dan server mencari record session.
Dengan otentikasi berbasis token, server dapat menghindari menyimpan state session untuk setiap permintaan pengguna. Sebaliknya, klien memegang token (seperti JWT) dan menyertakannya pada panggilan API. Ini populer untuk API karena:
Nuansa penting: “stateless” tidak berarti “tanpa pengecekan server-side sama sekali.” Banyak sistem nyata masih memvalidasi token terhadap status pengguna, rotasi kunci, atau mekanisme pencabutan.
JWT umum membawa bukti autentikasi (Anda sudah masuk) dan petunjuk otorisasi dasar (peran, izin, scope)—tetapi server Anda tetap harus menegakkan aturan otorisasi.
Anda sering melihat JWT digunakan sebagai access token di:
JWT adalah string ringkas yang terdiri dari tiga bagian, masing-masing di-Base64URL-kan dan dipisah oleh titik:
header.payload.signature
Contoh (disamarkan):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c…
Header menjelaskan bagaimana token dibuat—terpenting adalah algoritma penandatanganan (mis. HS256, RS256/ES256) dan tipe token.
Field umum:
typ: sering "JWT" (sering diabaikan dalam praktik)alg: algoritma penandatanganan yang digunakankid: identifier kunci untuk membantu verifier memilih kunci yang tepat saat rotasiCatatan keamanan: jangan percaya header begitu saja. Terapkan allowlist algoritma yang benar-benar Anda gunakan, dan jangan terima alg: "none".
Payload berisi “klaim” (field) tentang pengguna dan konteks token: untuk siapa, siapa yang menerbitkan, dan kapan kadaluarsa.
Penting: JWT tidak terenkripsi secara default. Base64URL membuat token aman untuk URL; itu tidak menyembunyikan data. Siapa pun yang mendapatkan token bisa mendekode header dan payload.
Karena itu, hindari menaruh rahasia (kata sandi, API key) atau data pribadi sensitif ke dalam JWT.
Signature dibuat dengan menandatangani header + payload menggunakan kunci:
Signature memberikan integritas: memungkinkan server memverifikasi token tidak diubah dan diterbitkan oleh signer tepercaya. Signature tidak memberikan kerahasiaan.
Karena JWT menyertakan header dan payload pada setiap permintaan tempat ia dikirim, token yang lebih besar berarti lebih banyak bandwidth dan overhead. Jaga klaim tetap ringkas dan gunakan identifier daripada data besar.
Klaim umumnya terbagi menjadi dua: registered (nama standar) dan kustom (field aplikasi Anda).
iss (issuer): siapa yang membuat tokensub (subject): tentang siapa token ini (sering id pengguna)aud (audience): untuk siapa token ini ditujukan (mis. API tertentu)exp (expiration time): kapan token harus berhenti diterimaiat (issued at): kapan token dibuatnbf (not before`): token tidak boleh diterima sebelum waktu iniSertakan hanya apa yang benar-benar dibutuhkan layanan penerima untuk membuat keputusan otorisasi.
Contoh yang baik:
user_id)Hindari klaim “kenyamanan” yang menduplikasi banyak data profil. Mereka membuat token bengkak, cepat kadaluarsa, dan meningkatkan dampak jika token bocor.
Karena payload dapat dibaca, jangan simpan:
Jika perlu informasi sensitif, simpan di server dan letakkan hanya referensi (mis. ID) di token—atau gunakan format token terenkripsi (JWE) bila sesuai.
Penandatanganan bukan enkripsi.
Saat JWT diterbitkan, server menandatangani header + payload terenkode. Saat token disajikan nanti, server menghitung ulang signature dan membandingkannya. Jika seseorang mengubah walau satu karakter (mis. "role":"user" menjadi "role":"admin"), verifikasi gagal dan token ditolak.
JWT adalah format token. OAuth 2.0 dan OpenID Connect (OIDC) adalah protokol yang menjelaskan bagaimana aplikasi meminta, menerbitkan, dan menggunakan token.
OAuth 2.0 terutama soal otorisasi: memberi aplikasi hak mengakses API atas nama pengguna tanpa membagikan kata sandi pengguna.
Access token biasanya berumur pendek (menit). Masa berlaku pendek membatasi kerusakan jika token bocor.
OIDC menambahkan autentikasi (siapa pengguna) di atas OAuth 2.0 dan memperkenalkan ID token, yang biasanya berupa JWT.
Aturan penting: jangan gunakan ID token untuk memanggil API.
Jika Anda ingin konteks lebih tentang flow praktis, lihat /blog/jwt-authentication-flow.
Flow tipikal:
Pengguna masuk (email/password, SSO, dll.). Jika berhasil, server membuat JWT (sering access token) dengan klaim penting seperti subject dan expiry.
Server menandatangani token dan mengembalikannya ke klien (web app, mobile app, atau layanan lain).
Untuk endpoint terlindung, klien menyertakan JWT di header Authorization:
Authorization: Bearer <JWT>
Sebelum melayani permintaan, API biasanya memeriksa:
exp (belum kadaluarsa)iss (issuer yang diharapkan)aud (ditujukan untuk API ini)Jika semua pengecekan lulus, API menganggap pengguna terautentikasi dan menerapkan aturan otorisasi (mis. izin per-record).
Karena jam sistem bisa bergeser, banyak sistem mengizinkan sedikit clock skew saat memvalidasi klaim berbasis waktu seperti exp (dan kadang nbf). Jaga skew kecil agar tidak memperpanjang masa berlaku token lebih dari yang dimaksud.
Pilihan penyimpanan menentukan apa yang dapat dicuri penyerang dan seberapa mudah mereka dapat memutar ulang token.
Penyimpanan di memori (sering direkomendasikan untuk SPA) menyimpan access token di state JS. Token hilang saat refresh dan mengurangi risiko “diambil belakangan”, tetapi bug XSS masih bisa membacanya saat halaman berjalan. Pasangkan dengan akses token berumur pendek dan flow refresh.
localStorage/sessionStorage mudah tapi berisiko: setiap kerentanan XSS dapat mengekstrak token dari storage web. Jika menggunakannya, pencegahan XSS tidak bisa ditawar (CSP, escaping output, kebersihan dependency) dan jaga token berumur pendek.
Cookie aman (sering default teraman untuk web) menyimpan token di cookie HttpOnly sehingga JavaScript tidak bisa membacanya—mengurangi dampak pencurian token via XSS. Trade-off-nya adalah risiko CSRF, karena browser melampirkan cookie otomatis.
Jika memakai cookie, setel:
HttpOnlySecure (HTTPS saja)SameSite=Lax atau SameSite=Strict (beberapa flow lintas situs mungkin perlu SameSite=None; Secure)Pertimbangkan juga token CSRF untuk permintaan yang mengubah state.
Di iOS/Android, simpan token di penyimpanan aman platform (Keychain / Keystore-backed storage). Hindari file biasa atau preferences. Jika model ancaman Anda mencakup perangkat yang di-root/jailbreak, anggap ekstraksi mungkin terjadi dan andalkan token berumur pendek serta kontrol server-side.
Batasi apa yang dapat dilakukan token: gunakan scope/claims minimal, buat access token berumur pendek, dan hindari menanam data sensitif.
JWT praktis, tetapi banyak insiden berasal dari kesalahan yang mudah diprediksi. Anggap JWT seperti uang tunai: siapa pun yang mendapatkannya biasanya bisa menggunakannya.
Jika token bertahan berhari-hari atau berminggu-minggu, kebocoran memberi penyerang jendela waktu sebesar itu.
Utamakan access token berumur pendek (menit) dan refresh mereka melalui mekanisme yang lebih aman. Jika perlu “ingat saya”, lakukan dengan refresh token dan kontrol server-side.
Signature yang valid tidak cukup. Verifikasi iss dan aud, serta validasi klaim berbasis waktu seperti exp dan nbf.
Dekode bukan verifikasi. Selalu verifikasi signature di server dan terapkan izin di sisi server.
Hindari menaruh JWT di query params. Mereka bisa berakhir di riwayat browser, log server, alat analitik, dan header referrer.
Gunakan Authorization: Bearer ... sebagai gantinya.
Asumsikan kunci dan token bisa bocor. Rotasi kunci tanda tangan, gunakan kid untuk mendukung rotasi mulus, dan miliki strategi pencabutan (masa berlaku pendek + kemampuan menonaktifkan akun/session). Untuk panduan penyimpanan, lihat /blog/where-to-store-jwts-safely.
JWT berguna, tetapi bukan pilihan terbaik secara otomatis. Pertanyaan sebenarnya: apakah Anda mendapat manfaat dari token yang self-contained dan bisa diverifikasi tanpa lookup database pada setiap permintaan.
Untuk aplikasi web tradisional yang dirender server di mana invalidasi mudah penting, session server-side dengan cookie HttpOnly seringkali lebih sederhana dan lebih aman.
Pilih JWT jika Anda perlu verifikasi stateless antar layanan dan dapat menjaga token berumur pendek.
Hindari JWT jika Anda butuh pencabutan instan, berencana menyimpan data sensitif di token, atau bisa menggunakan cookie session tanpa hambatan.
Verifikasi menggunakan kunci yang benar dan algoritma yang di-allowlist. Tolak signature yang tidak valid—tanpa pengecualian.
exp (kadaluarsa)Pastikan token belum kedaluwarsa.
nbf (not before)Jika ada, pastikan token tidak digunakan terlalu awal.
aud (audience)Konfirmasi token memang ditujukan untuk API/layanan Anda.
iss (issuer)Konfirmasi token berasal dari issuer yang diharapkan.
Validasi format token, terapkan ukuran maksimum, dan tolak tipe klaim yang tidak diharapkan untuk mengurangi bug edge-case.
HS256 (kunci simetris): satu secret bersama untuk menandatangani dan memverifikasi.
RS256 / ES256 (kunci asimetris): private key menandatangani; public key memverifikasi.
Aturan praktis: jika lebih dari satu sistem independen perlu memverifikasi token (atau Anda tidak sepenuhnya mempercayai setiap verifier), pilih RS256/ES256.
iss, aud, dan user ID hanya jika kebijakan mengizinkan).Apakah JWT terenkripsi?
Tidak secara default. Sebagian besar JWT ditandatangani, bukan dienkripsi, artinya konten dapat dibaca siapa pun yang punya token. Gunakan JWE atau jangan letakkan data sensitif dalam JWT.
Bisakah saya mencabut JWT?
Tidak mudah jika hanya mengandalkan access token self-contained. Pendekatan umum meliputi token akses berumur pendek, deny-list untuk peristiwa berisiko tinggi, atau refresh token dengan rotasi.
Berapa lama exp sebaiknya?
Sesingkat mungkin sesuai UX dan arsitektur Anda. Banyak API memakai menit untuk access token, dipasangkan dengan refresh token untuk sesi yang lebih lama.
Jika Anda mengimplementasikan otentikasi JWT di API atau SPA baru, banyak pekerjaan yang repetitif: memasang middleware, memvalidasi iss/aud/exp, menyetel flag cookie, dan menjaga agar penanganan token tidak masuk log.
Dengan Koder.ai, Anda bisa mempercepat pembuatan aplikasi web (React), layanan backend (Go + PostgreSQL), atau aplikasi mobile Flutter melalui workflow berbasis chat—lalu iterasi dalam planning mode, gunakan snapshot dan rollback saat menyempurnakan keamanan, dan ekspor kode sumber saat siap. Ini cara praktis mempercepat pembuatan flow autentikasi berbasis JWT sambil tetap mengendalikan logika verifikasi, strategi rotasi kunci, dan pengaturan deployment/hosting (termasuk domain kustom).
JWT (JSON Web Token) adalah string ringkas yang aman untuk URL yang membawa klaim (field data) dan dapat diverifikasi oleh server. Biasanya dikirim pada permintaan API melalui:
Authorization: Bearer <token>Intinya: server dapat memvalidasi integritas token (melalui signature) tanpa perlu menyimpan record session per pengguna untuk setiap permintaan.
Otentikasi berbasis session biasanya menyimpan status di server (record session yang dihubungkan dengan cookie/session ID). Dengan otentikasi berbasis JWT, klien menyertakan token yang ditandatangani pada setiap permintaan, dan API memvalidasinya.
JWT populer untuk API dan arsitektur multi-layanan karena verifikasi dapat dilakukan secara lokal, mengurangi kebutuhan penyimpanan session bersama.
“Stateless” sering kali masih melibatkan pengecekan server-side seperti daftar pencabutan, status pengguna, atau rotasi kunci.
JWT terdiri dari tiga bagian yang di-Base64URL-kan dan dipisah dengan titik:
header.payload.signatureHeader menjelaskan bagaimana token ditandatangani, payload berisi klaim (mis. sub, exp, aud), dan signature memungkinkan server mendeteksi perubahan.
Tidak. JWT standar biasanya ditandatangani, bukan dienkripsi.
Jika Anda butuh kerahasiaan, pertimbangkan JWE (token terenkripsi) atau simpan data sensitif di server dan letakkan hanya referensi di JWT.
Signature memungkinkan server memverifikasi token tidak diubah dan diterbitkan oleh pihak yang memegang kunci penandatangan.
Signature tidak:
exp secara otomatisAnggap token sebagai kredensial: jika bocor, token dapat dipakai kembali sampai kadaluarsa.
alg memberi tahu verifier algoritma yang dipakai (mis. HS256 vs RS256). kid adalah identifier kunci yang membantu memilih kunci verifikasi saat rotasi.
Aturan keamanan singkat:
Mulailah dengan klaim terdaftar standar dan buat klaim kustom seminimal mungkin.
Klaim terdaftar umum:
JWT adalah format token; OAuth 2.0 dan OpenID Connect adalah protokol.
Pemetaan umum:
Untuk aplikasi browser, opsi umum:
localStorage/sessionStorage: mudah, tetapi rentan terhadap XSS. Jika digunakan, pencegahan XSS wajib dan token harus berumur pendek.Minimal, validasi:
exp (belum kadaluarsa)iss (issuer yang diharapkan)aud (ditujukan ke API Anda)nbf (jika ada)Tambahkan pengamanan praktis:
alg sembarangan.alg: "none".kid yang tidak tepercaya menyebabkan lookup kunci yang tidak aman.iss (issuer)sub (subjek / id pengguna)aud (audience / API yang dituju)exp (kadaluarsa)iat (issued at)nbf (not before)Hindari menaruh rahasia atau data pribadi sensitif di payload karena dapat dibaca jika token terekspos.
Penting: jangan gunakan ID token untuk memanggil API hanya karena bentuknya mirip JWT access token.
Jika pakai cookie, setel:
HttpOnlySecure (HTTPS saja)SameSite=Lax atau SameSite=Strict (beberapa flow lintas situs mungkin butuh SameSite=None; Secure)Pertimbangkan juga token CSRF untuk permintaan yang mengubah state. Secara umum, batasi hak token dan buat token berumur pendek.