Klaim Kedaluwarsa dan Issued-At di JWT: Cara Unix Timestamp Menggerakkan Autentikasi Token

Klaim kedaluwarsa JWT exp dan iat ditampilkan sebagai timestamp Unix dalam diagram payload token web JSON

Setiap kali pengguna masuk ke aplikasi SaaS, sebuah auth token dibuat dan dikirimkan ke browser atau aplikasi mobile mereka. Token itu membawa jam tersembunyi di dalamnya. Field JWT expiration, yang disimpan sebagai Unix timestamp biasa, memberi tahu setiap server yang membacanya kapan harus berhenti mempercayai kredensial tersebut. Salah menetapkan timestamp itu bahkan beberapa detik saja bisa membuat pengguna terkunci terlalu cepat, atau lebih buruk lagi, membiarkan sesi tetap valid jauh lebih lama dari yang diizinkan kebijakan keamananmu. Memahami cara kerja claim pada JSON web token, terutama exp dan iat , adalah salah satu hal paling praktis yang bisa dilakukan tim SaaS untuk memperketat autentikasi tanpa menambah hambatan bagi pengguna.

Poin Utama:

  • Claim exp dan iat dalam sebuah JWT JSON web token selalu berupa Unix timestamp yang diukur dalam detik penuh, bukan milidetik.
  • Perbedaan jam antar server (clock skew) bisa diam-diam membatalkan token atau memperpanjang sesi melebihi batas kebijakan - toleransi 60 detik adalah solusi standar industri.
  • Menetapkan token expiry terlalu panjang meningkatkan risiko kebocoran; terlalu pendek merusak pengalaman pengguna. Ada formula konkret untuk menentukan nilai yang tepat.
  • Kamu bisa men-decode dan memverifikasi timestamp JSON web token mana pun dalam satuan detik menggunakan konverter epoch Unix, tanpa perlu library tambahan.

Apa Itu JWT dan Mengapa Timestamp Ada di Dalamnya

Sebuah JSON web token adalah kredensial ringkas dan URL-safe yang terdiri dari tiga bagian yang di-encode dengan Base64 dan dipisahkan oleh titik: header, payload, dan signature. Payload adalah tempat data sensitif terhadap waktu disimpan. Karena JWT bersifat stateless, server tidak perlu mencari sesi di database untuk memvalidasinya. Sebagai gantinya, server membaca claim yang tertanam dalam payload dan mempercayai signature kriptografis. Desain ini cepat dan skalabel, tetapi menciptakan batasan nyata: begitu token diterbitkan, server tidak bisa "menghapusnya". Satu-satunya cara andal untuk membatasi masa berlakunya adalah dengan menyematkan timestamp kedaluwarsa langsung di dalam token itu sendiri.

Inilah mengapa waktu, khususnya Unix epoch time, menjadi inti dari keamanan JWT. Spesifikasi RFC 7519 yang mendefinisikan JWT mewajibkan claim berbasis waktu dinyatakan sebagai nilai "NumericDate", yaitu jumlah detik sejak 1 Januari 1970 UTC. Tanpa zona waktu. Tanpa format lokal. Hanya sebuah integer yang bisa dibandingkan oleh server mana pun di seluruh dunia dengan jam internalnya sendiri.

Struktur JWT yang menampilkan header, payload, dan signature dengan claim exp dan iat

Penjelasan Claim exp dan iat

Spesifikasi JWT mendefinisikan beberapa claim terdaftar. Dua yang paling penting untuk manajemen siklus hidup token adalah:

  • exp (Expiration Time): Timestamp setelah token tidak boleh diterima lagi. Server wajib menolak token apa pun di mana waktu saat ini sama dengan atau lebih besar dari nilai ini. Inilah mekanisme inti di balik JWT expiration.
  • iat (Issued At): Timestamp saat token dibuat. Claim iat tidak diberlakukan secara default, tetapi sangat berguna. Claim ini memungkinkan kamu menghitung usia sebuah token, menerapkan kebijakan usia maksimum secara independen dari exp , dan mendeteksi token yang diterbitkan dengan mencurigakan jauh di masa lalu.

Claim ketiga, nbf (Not Before), mendefinisikan waktu paling awal token berlaku. Claim ini jarang digunakan, tetapi mengikuti format Unix timestamp yang sama.

Ketiga nilai tersebut adalah integer. Jika sistemmu menghasilkannya dalam milidetik (kesalahan umum saat menggunakan Date.now() di JavaScript), angka yang dihasilkan akan sekitar 1.000 kali lebih besar dari yang seharusnya. Server yang memeriksa exp terhadap epoch detik saat ini akan melihat token yang tampaknya kedaluwarsa pada tahun 33.658 dan tidak akan pernah menolaknya. Ini adalah bug produksi nyata yang telah memengaruhi banyak tim SaaS.

Contoh Nyata: Men-decode Timestamp Token Secara Langsung

Misalkan layanan autentikasi kamu menerbitkan payload JWT berikut setelah pengguna masuk pada pukul 10:00 UTC, 1 Juli 2025:

{
  "sub": "user_8821",
  "iat": 1751364000,
  "exp": 1751367600,
  "role": "admin"
}

Mari kita uraikan arti angka-angka tersebut:

Claim Unix Timestamp Waktu Terbaca (UTC) Arti
iat 1751364000 2025-07-01 10:00:00 Token diterbitkan pada saat ini
exp 1751367600 2025-07-01 11:00:00 Token kedaluwarsa tepat 1 jam kemudian

Selisihnya tepat 3.600 detik, yaitu satu jam. Server mana pun yang menerima token ini setelah pukul 11:00:00 UTC harus menolaknya. Untuk memverifikasi ini secara manual, kamu cukup mengurangi iat dari exp : 1751367600 - 1751364000 = 3600 detik. Kamu bisa mengonfirmasi padanan waktu yang terbaca dari nilai-nilai ini secara instan menggunakan konverter Unix timestamp - itulah jenis pengecekan cepat yang mencegah bug milidetik vs. detik yang disebutkan sebelumnya.

Untuk konteks lebih lanjut tentang cara database menyimpan nilai-nilai ini, lihat panduan kami tentang Unix timestamp di database, karena format integer yang sama berlaku baik saat kamu menyimpan exp dalam token maupun dalam tabel audit log.

Clock Skew: Pembunuh Token yang Tak Terlihat

Ada satu kendala nyata yang sering mengejutkan tim pengembang. Dalam sistem terdistribusi, server autentikasi dan server API kamu adalah dua mesin yang berbeda. Jam sistem keduanya disinkronkan melalui NTP, tetapi tidak pernah benar-benar selaras sempurna. Perbedaan 30 hingga 90 detik adalah hal umum di lingkungan cloud.

Bayangkan skenario ini: token dengan exp = 1751367600 divalidasi oleh server API yang jam-nya menunjukkan 1751367610, hanya 10 detik setelah waktu kedaluwarsa. Token ditolak. Pengguna mendapat error 401. Dari sudut pandang mereka, mereka baru saja masuk dan aplikasinya tiba-tiba bermasalah.

Solusi standarnya adalah dengan membangun toleransi clock skew ke dalam logika validasi kamu. Sebagian besar library JWT mendukung parameter leeway. Nilai 60 detik diterima secara luas dan direferensikan dalam spesifikasi OpenID Connect Core. Tetapkan nilainya, dokumentasikan, dan pastikan setiap layanan dalam stack kamu menggunakan nilai yang sama.

Aturan praktis: Tambahkan leeway 60 detik pada validasi exp . Jangan pernah menambahkan leeway pada pengecekan iat , karena itu akan memungkinkan penerimaan token yang diterbitkan di masa depan - tanda bahaya untuk serangan replay.

Memilih Token Expiry yang Tepat untuk Produk SaaS Kamu

Nilai token expiry yang tepat bergantung pada sensitivitas aplikasi dan perilaku sesi yang diharapkan. Berikut kerangka praktisnya:

  • Aplikasi dengan sensitivitas tinggi (perbankan, layanan kesehatan, dasbor admin): 15 hingga 30 menit untuk access token. Gunakan refresh token untuk memperbarui sesi secara diam-diam.
  • Aplikasi SaaS standar (manajemen proyek, CRM, analitik): 1 hingga 8 jam. Sesuaikan dengan durasi sesi kerja yang umum.
  • API risiko rendah atau hanya baca: Hingga 24 jam, tetapi kombinasikan dengan rotasi token pada aksi sensitif.
  • Service token untuk komunikasi antar mesin (machine-to-machine): Bisa lebih panjang (hari atau minggu), tetapi harus dibatasi cakupannya dan dirotasi secara terjadwal.

Formula berguna untuk menghitung nilai exp saat token diterbitkan:

// Contoh Node.js
const iat = Math.floor(Date.now() / 1000); // waktu saat ini dalam detik
const ttl = 3600; // time-to-live: 1 jam dalam detik
const exp = iat + ttl;

const payload = {
  sub: userId,
  iat: iat,
  exp: exp
};

Perhatikan pembagian eksplisit dengan 1000 untuk mengonversi dari milidetik ke detik. Satu baris ini mencegah bug timestamp JWT yang paling umum terjadi pada aplikasi JavaScript.

Langkah Konkret Mengimplementasikan JWT Expiration yang Aman

Berikut daftar periksa konkret yang bisa kamu terapkan pada sistem autentikasi SaaS mana pun sekarang juga:

  1. Selalu sertakan iat dan exp . Claim iat secara teknis bersifat opsional, tetapi memberikan jejak audit dan memungkinkan penerapan usia maksimum secara independen dari waktu kedaluwarsa.
  2. Verifikasi format timestamp sebelum deploy. Decode token kamu dan periksa bahwa exp adalah integer 10 digit. Nilai 13 digit berarti milidetik ikut masuk.
  3. Tetapkan leeway clock skew sebesar 60 detik pada middleware validasi kamu. Terapkan secara konsisten di setiap layanan yang menggunakan auth token.
  4. Gunakan access token berumur pendek dikombinasikan dengan refresh token. Access token 15 menit yang dipasangkan dengan refresh token 7 hari jauh lebih aman daripada satu access token 7 hari, karena refresh token bisa dicabut di sisi server.
  5. Catat nilai iat pada setiap permintaan yang terautentikasi. Ini memungkinkan kamu mendeteksi anomali, seperti token yang sama digunakan dari dua wilayah geografis berbeda secara bersamaan.
  6. Uji kedaluwarsa di staging dengan waktu yang dipercepat. Simulasikan jam agar melompat melewati nilai exp dan konfirmasi bahwa aplikasi kamu menangani error 401 dengan baik, bukan crash atau masuk ke loop.

Jika kamu perlu mengonversi nilai exp mentah dari sebuah token menjadi tanggal yang terbaca, atau memverifikasi timestamp yang harus ditetapkan untuk durasi tertentu, konverter epoch di halaman utama kami menangani keduanya secara instan, tanpa perlu kode apa pun.

Kesimpulan

JWT expiration bukanlah konsep yang rumit, tetapi ini adalah area di mana kesalahan kecil bisa menciptakan celah keamanan yang besar. Claim exp dan iat hanyalah integer - Unix timestamp yang dihitung dalam detik dari epoch. Kesederhanaan itulah kekuatannya: setiap server, setiap bahasa pemrograman, dan setiap platform bisa membandingkan dua angka tanpa ambiguitas. Keahlian sesungguhnya ada pada penerapannya yang benar - memilih durasi token expiry yang masuk akal, menangani clock skew dengan jendela toleransi, dan menangkap kesalahan milidetik vs. detik sebelum masuk ke produksi. Bangun kebiasaan-kebiasaan ini ke dalam pipeline autentikasi kamu, dan implementasi JSON web token kamu akan menjadi sesuatu yang sekaligus aman dan mudah dipelihara.

Alat konverter Unix timestamp untuk verifikasi JWT expiration

Verifikasi Timestamp JWT Secara Instan - Tanpa Kode

Tempel timestamp Unix mana pun dari payload JWT dan konversi ke tanggal yang terbaca hanya dengan satu klik. Tangkap kesalahan milidetik vs. detik sebelum sampai ke produksi.

Coba Alat Gratis Kami →

exp (Expiration Time) adalah Unix timestamp setelah token tidak valid dan harus ditolak. iat (Issued At) adalah timestamp saat token dibuat. Keduanya adalah integer dalam satuan detik. Claim iat bersifat opsional, tetapi berguna untuk audit dan penerapan kebijakan usia maksimum token.

Unix timestamp adalah integer yang bebas zona waktu, sehingga tidak ambigu di semua server dan wilayah. String tanggal berformat seperti "2025-07-01T10:00:00" bisa disalahartikan berdasarkan pengaturan lokal atau zona waktu. Perbandingan integer juga lebih cepat dan lebih kecil kemungkinan error dibandingkan parsing string dalam sistem autentikasi dengan throughput tinggi.

Token yang berumur panjang tetap valid meskipun akun pengguna telah dibobol atau izin mereka berubah. Karena JWT bersifat stateless, server tidak bisa mencabutnya di tengah masa berlaku. Jika penyerang mencuri token dengan masa berlaku 30 hari, mereka memiliki akses selama 30 hari. Jendela kedaluwarsa yang pendek dikombinasikan dengan refresh token secara signifikan memperkecil jendela risiko ini.

Di JavaScript, selalu gunakan Math.floor(Date.now() / 1000) saat menghasilkan nilai iat atau exp . Date.now() yang mentah mengembalikan nilai dalam milidetik. Membaginya dengan 1000 mengonversinya ke integer berbasis detik yang disyaratkan oleh spesifikasi JWT. Verifikasi dengan memeriksa bahwa timestamp kamu adalah angka 10 digit, bukan 13 digit.

Clock skew adalah perbedaan waktu kecil antara jam sistem dua server dalam sistem terdistribusi. Bahkan perbedaan 30 detik bisa menyebabkan token yang valid ditolak jika jam server yang memvalidasi sedikit lebih maju. Solusi standarnya adalah mengonfigurasi leeway 60 detik di library validasi JWT kamu untuk menyerap drift NTP yang normal.