Logout di JWT: Dua Pendekatan dan Kenapa Saya Pilih Redis Blacklist
JWT stateless — server tidak menyimpan state token. Artinya ketika user logout, token yang sudah diterbitkan tetap valid sampai expired. Tidak ada mekanisme bawaan untuk "cabut" token yang sudah keluar.
Saya punya dua opsi untuk solve ini.
Opsi pertama: simpan token di PostgreSQL.
Setiap logout, token disimpan ke tabel blacklist. Setiap request authenticated, cek tabel itu dulu sebelum lanjut.
Masalahnya jelas: PostgreSQL baca dari disk. Setiap request ke endpoint protected jadi dua query — satu cek blacklist, satu ambil data. Di scale kecil tidak terasa, tapi ini trade-off yang tidak perlu diambil kalau ada alternatif yang lebih tepat.
Opsi kedua: Redis blacklist.
Redis menyimpan data di memory — pengecekan "apakah key ini exist?" selesai dalam mikrodetik. Dan Redis punya TTL bawaan, jadi token expired otomatis terhapus dari blacklist. Tidak numpuk.
Trade-off Redis blacklist tetap ada: semakin banyak user aktif, blacklist makin besar. Solusi yang lebih scalable adalah short-lived token (15 menit) + refresh token yang bisa dicabut — tapi untuk project ini, Redis blacklist sudah cukup dan trade-off-nya saya terima dengan sadar.
Implementasinya sederhana: logout menyimpan token ke Redis dengan TTL 24 jam (sama dengan expiry token). Middleware cek Redis sebelum izinkan request lanjut. Kalau token ada di blacklist, langsung 401.
Satu hal yang saya pelajari dari proses ini: keputusan teknis yang baik bukan tentang pilih yang paling canggih — tapi pilih yang trade-off-nya paling masuk akal untuk konteks yang ada.