JWT (JSON Web Token) — adalah format ringkas untuk mentransfer data antar pihak dalam bentuk objek JSON yang dilindungi oleh tanda tangan digital. Token dapat ditandatangani menggunakan HMAC (kunci simetris) atau RSA/ECDSA (pasangan asimetris), yang menjamin integritas dan keaslian data. Menurut IETF RFC 7519, 2015, JWT digunakan di jutaan aplikasi untuk autentikasi, pertukaran claims yang aman, dan sebagai format ID Token di OpenID Connect.
Hal Penting
JSON Web Token (JWT) — adalah standar terbuka (RFC 7519) yang mendefinisikan cara ringkas dan mandiri untuk mentransfer informasi antar pihak dalam bentuk objek JSON. Informasi di JWT disebut claims — pernyataan tentang subjek (pengguna) dan atribut tambahan. Setiap claim adalah pasangan kunci-nilai: ID pengguna, peran, waktu kedaluwarsa, penerbit.
JWT disebut mandiri karena semua informasi yang diperlukan untuk verifikasi terdapat di dalam token itu sendiri. Server tidak perlu mengakses database atau penyimpanan eksternal untuk memastikan validitas token — cukup memverifikasi tanda tangan. Properti ini membuat JWT ideal untuk sistem terdistribusi dan arsitektur mikrolayanan, di mana beberapa layanan harus mengautentikasi permintaan tanpa penyimpanan sesi bersama.
Menurut data Auth0, 2025, lebih dari 65% aplikasi mobile dan web menggunakan JWT sebagai format token utama untuk autentikasi API, melampaui token opaque dan pengidentifikasi sesi.
JWT terdiri dari tiga bagian yang dipisahkan oleh titik: header.payload.signature. Setiap bagian adalah JSON yang dikodekan Base64url. Mari kita bahas setiap bagian secara detail.
Header berisi dua bidang wajib: alg (algorithm — algoritma tanda tangan) dan typ (type — jenis token, selalu “JWT”). Algoritma dapat bersifat simetris (HS256 — HMAC dengan SHA-256) atau asimetris (RS256 — RSA dengan SHA-256, ES256 — ECDSA dengan P-256). Algoritma asimetris lebih disukai karena memungkinkan klien memverifikasi tanda tangan tanpa memiliki kunci rahasia.
Contoh header yang didekode:
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-id-1"
}
Payload berisi claims — pernyataan tentang subjek. Claims dibagi menjadi tiga jenis: terdaftar (iss, sub, aud, exp, nbf, iat, jti), publik (ditentukan oleh pengembang di IANA Registry) dan privat (disepakati antar pihak). sub (subject) — pengidentifikasi unik pengguna. exp (expiration) — stempel waktu kedaluwarsa token. iss (issuer) — penerbit token.
{
"sub": "user-abc-123",
"iss": "https://auth.example.com",
"aud": "my-mobile-app",
"exp": 1812345678,
"iat": 1812342078,
"role": "premium_user"
}
Signature dibuat dengan menerapkan algoritma tanda tangan pada gabungan header dan payload menggunakan kunci rahasia atau privat. Rumus: HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret) untuk HMAC, atau RSASHA256(...) untuk algoritma asimetris. Penerima menghitung tanda tangan dengan cara yang sama dan membandingkannya dengan yang diterima — jika cocok, data tidak diubah.
Proses kerja JWT terdiri dari dua fase: pembuatan (penerbitan) token oleh server autentikasi dan verifikasi token oleh klien atau server sumber daya. Server autentikasi menerima kredensial pengguna, membuat payload dengan claims dan menandatanganinya. JWT yang dihasilkan dikirim ke klien sebagai respons terhadap permintaan masuk atau di badan respons OAuth 2.0 / OpenID Connect.
Dalam aplikasi mobile JWT digunakan sebagai berikut: setelah berhasil masuk, pengguna menerima access token dalam format JWT. Aplikasi menyimpannya di penyimpanan aman (Keychain di iOS, EncryptedSharedPreferences di Android). Setiap permintaan ke API, aplikasi menambahkan header Authorization: Bearer <token>. Server API memverifikasi tanda tangan JWT, mengekstrak claims dan berdasarkan itu membuat keputusan akses — tanpa mengakses database.
Menurut data Google Codelabs, 2025, penggunaan JWT di Firebase Authentication mengurangi jumlah permintaan ke server autentikasi sebesar 40–60% dibandingkan dengan token sesi, karena data diverifikasi secara lokal di setiap mikrolayanan. Ini sangat penting dalam arsitektur dengan beban tinggi, di mana setiap milidetik penundaan memengaruhi pengalaman pengguna. Pada 50.000 permintaan per menit, beralih ke JWT dapat menghemat hingga 10 instans server yang memproses permintaan introspection.
JWT dan Session Token menyelesaikan tugas yang sama — autentikasi permintaan — tetapi berbeda secara fundamental dalam arsitektur. Session Token adalah string pengidentifikasi acak yang merujuk pada data sesi yang disimpan di server (stateful). JWT — token mandiri yang berisi semua data di dalamnya (stateless).
| Parameter | JWT | Session Token |
|---|---|---|
| Penyimpanan data | Di dalam token (mandiri) | Di server (penyimpanan sesi) |
| Penskalaan | Tidak memerlukan penyimpanan bersama | Memerlukan Redis/DB untuk multi-server |
| Pencabutan token | Kompleks (perlu daftar hitam) | Sederhana (hapus sesi dari DB) |
| Ukuran | Besar (500–2000 byte) | Kecil (16–64 byte) |
| Verifikasi tanda tangan | Kriptografis | Tidak (perbandingan string) |
JWT unggul dalam sistem terdistribusi: mikrolayanan dapat memverifikasi token secara lokal tanpa penyimpanan bersama. Misalnya, dalam arsitektur dengan lima mikrolayanan, setiap layanan memverifikasi JWT dalam 1–2 ms tanpa panggilan jaringan, sementara session token memerlukan akses ke Redis terpusat di setiap permintaan, menambahkan 10–30 ms penundaan. Namun, JWT sulit dicabut — jika token sudah diterbitkan, token berlaku hingga kedaluwarsa. Session Token mudah dicabut dengan menghapus catatan dari DB atau Redis.
Untuk aplikasi mobile, pendekatan gabungan — JWT dengan masa hidup pendek (15–30 menit) dan Refresh Token — memberikan keseimbangan antara kinerja dan keamanan. JWT digunakan untuk akses API, dan refresh token (biasanya opaque) untuk mendapatkan JWT baru. Jika JWT dikompromikan, penyerang memiliki akses selama 15–30 menit; jika refresh token dikompromikan, sesi diblokir melalui rotasi dan deteksi penggunaan ulang.
Keamanan JWT tergantung pada implementasi yang benar. Kerentanan yang paling umum adalah serangan “alg none”: penyerang mengubah header token menjadi “alg”: “none”, dan server tanpa memeriksa algoritma menerima token palsu. Perlindungan: selalu periksa apakah algoritma di header sesuai dengan yang diharapkan (RS256, ES256) dan tolak token dengan alg: none.
Kerentanan JWT juga meliputi: kunci rahasia lemah untuk HMAC (diretas dalam hitungan menit), kebocoran kunci privat (menandatangani data apa pun atas nama server), penyimpanan data sensitif di payload (JWT tidak mengenkripsi, hanya menandatangani), serangan melalui injeksi header JWK (memasukkan kunci publik sendiri). Penggunaan pustaka terverifikasi — Nimbus JOSE + JWT, jjwt (io.jsonwebtoken), PyJWT — mengurangi risiko eksploitasi kerentanan ini.
Tindakan perlindungan tambahan — JWK Thumbprint (RFC 7638): mengikat kunci publik ke token melalui sidik jari (thumbprint) di header. Jika server menyimpan thumbprint yang diharapkan untuk setiap klien, serangan injeksi header JWK menjadi tidak mungkin — server menolak kunci apa pun yang tidak cocok dengan yang terdaftar. OAuth Security Workshop 2025 merekomendasikan JWK Thumbprint sebagai perlindungan wajib untuk semua JWT yang digunakan di aplikasi keuangan dan medis.
Pustaka jjwt (auth0/java-jwt) memungkinkan pembuatan dan verifikasi JWT di aplikasi Android dalam beberapa baris. Dalam contoh di bawah, server menghasilkan token dengan sub dan role, dan klien memverifikasi tanda tangan. Untuk penyimpanan aman kunci rahasia di server, gunakan variabel lingkungan atau HSM (Hardware Security Module) — menyimpan kunci di kode atau file konfigurasi adalah kesalahan keamanan yang serius.
val secret = "my-256-bit-secret-key-here"
val token = JWT.create()
.withSubject("user-abc-123")
.withIssuer("auth.example.com")
.withClaim("role", "premium_user")
.withExpiresAt(Date(System.currentTimeMillis() + 3600000))
.sign(Algorithm.HMAC256(secret))
// Mengirim token ke klien
println("JWT: $token")
fun verifyToken(token: String): Boolean {
return try {
val decoded = JWT.require(Algorithm.HMAC256(secret))
.withIssuer("auth.example.com")
.build()
.verify(token)
// Tanda tangan valid, claims diekstrak
println("Subject: ${decoded.subject}")
true
} catch (e: Exception) {
println("Token invalid: ${e.message}")
false
}
}
Pertanyaan yang Sering Diajukan
Tidak. JWT ditandatangani, bukan dienkripsi — siapa pun dapat mendekode payload Base64 dan membaca data. Informasi sensitif (kata sandi, nomor kartu, data pribadi) harus dikirim hanya dalam bentuk terenkripsi melalui JWE (JSON Web Encryption).
ES256 (ECDSA dengan P-256) direkomendasikan — memberikan tingkat keamanan setara RSA 2048-bit dengan ukuran tanda tangan yang jauh lebih kecil. Untuk kompatibilitas dengan sistem lama, RS256 cocok. HS256 (HMAC) memerlukan pertukaran kunci rahasia yang aman, yang lebih sulit dalam arsitektur terdistribusi.
JWT tidak dapat dicabut secara langsung — berlaku hingga exp. Solusi: gunakan masa hidup pendek (15–30 menit), kelola daftar hitam jti (JWT ID) yang dicabut di server, atau kaitkan token dengan versi kunci rahasia. Refresh token dicabut dengan cara standar — dengan menghapus dari penyimpanan.
Bearer token — adalah konsep: token apa pun yang dapat digunakan pemegangnya (bearer) untuk akses. JWT — adalah format token tertentu. Bearer token bisa berupa JWT atau string opaque. JWT menambahkan ke konsep Bearer kemandirian dan verifikasi kriptografis.
JWT tipikal dengan tanda tangan RS256 berukuran 500–2000 byte. Jika payload berisi banyak claims khusus atau menggunakan tanda tangan asimetris dengan kunci besar, ukurannya bisa mencapai 4–5 KB. Ini secara signifikan lebih besar dari session token (16–64 byte), yang memengaruhi ukuran header HTTP.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga