JWT vs Session Authentication: Memahami Perbedaan dan Kapan Menggunakannya
## Introduction Dalam membangun aplikasi web modern, keamanan otentikasi adalah salah satu aspek yang tidak boleh diabaikan. Dua pendekatan populer un...

Introduction
Dalam membangun aplikasi web modern, keamanan otentikasi adalah salah satu aspek yang tidak boleh diabaikan. Dua pendekatan populer untuk mengelola sesi pengguna adalah JWT (JSON Web Token) dan Session-based authentication (biasa menggunakan cookie dan server-side storage). Meskipun keduanya bertujuan untuk mengidentifikasi pengguna yang telah login, cara kerjanya, kelebihan, dan kekurangannya sangat berbeda. Artikel ini akan menjelaskan konsep dasar masing-masing, memberikan contoh sederhana dalam Node.js/Express, dan membantu Anda memutuskan kapan sebaiknya menggunakan JWT atau Session.
Pembahasan
Apa itu Session Authentication?
- Konsep: Setelah login berhasil, server membuat sebuah session identifier (misal: ) dan menyimpan data sessi (user ID, role, dll.) di penyimpanan server seperti memori, Redis, atau database. Identifier ini lalu dikirim ke klien sebagai cookie (code
sessionId).codeSet-Cookie: sessionId=abc123; HttpOnly; Secure - Keamanan: Cookie biasanya ditandai dancode
HttpOnlysehingga tidak dapat diakses oleh JavaScript dan hanya dikirim melalui HTTPS.codeSecure - Kelebihan:
- Mudah untuk melakukan logout karena cukup menghapus data sessi di server.
- Ukuran cookie kecil (hanya ID), sehingga tidak menambah beban jaringan signifikan.
- Kekurangan:
- Memerlukan penyimpanan server yang harus di-skala (misalnya menggunakan Redis cluster) ketika aplikasi menggunakan banyak instance.
- Tidak cocok untuk arsitektur mikro‑layanan yang sepenuhnya stateless.
Apa itu JWT?
- Konsep: JWT adalah token yang dikodekan dalam format JSON dan ditandatangani secara kriptografis (HMAC atau RSA). Token berisi claims seperti (subject/user ID),code
sub(expiration), dan data kustom lain. Token ini dikirim ke klien (biasa dalam headercodeexpatau cookie) dan divalidasi oleh server hanya melalui verifikasi tanda tangan, tanpa perlu menyimpan state di server.codeAuthorization: Bearer <token> - Keamanan: Asalkan kunci rahasia (secret) atau kunci privat tidak bocor, token tidak dapat diubah tanpadeteksi.
- Kelebihan:
- Stateless: server tidak perlu menyimpan session, sehingga mudah di‑scale dan cocok untuk mikro‑layanan.
- Token dapat berisi informasi yang dibutuhkan oleh layanan lain (misal: role, permissions) tanpa perlu panggilan tambahan ke server otentikasi.
- Kekurangan:
- Ukuran token lebih besar (biasa beberapa ratus byte) karena mengandung payload yang ditandatangani.
- Pembatalan token sebelum masa berlaku () membutuhkan mekanisme tambahan seperti token blacklist atau revocation list.code
exp - Tidak disarankan untuk menyimpan data sensitif dalam payload karena token hanya base64url di‑encode (bisa dengan mudah didekode).
Kapan Memilih Mana?
| Situasi | Direkomendasikan |
|---|---|
| Aplikasi monolitik dengan sedikit instance, ingin logout instan, dan tidak mau mengelola ukuran token | Session |
| Sistem mikro‑layanan, API gateway, atau layanan yang perlu skala horizontal tanpa menyimpan state | JWT |
| Butuh token yang dapat dipakai oleh banyak layanan pihak ketiga (misal: login dengan OAuth2) | JWT |
| Kebutuhan akan pencabutan akses segera (misal: perubahan password) tanpa menunggu token kadaluarsa | Session ( atau JWT + blacklist ) |
Contoh (jika ada)
Berikut contoh sederhana mengimplementasikan keduanya dengan Node.js + Express. Kita asumsikan sudah ada fungsi
verifyPassword(email, password)userjavascript// ---- Dependency ---- const express = require('express'); const jwt = require('jsonwebtoken'); const session = require('express-session'); const RedisStore = require('connect-redis')(session); const redis = require('redis'); const app = express(); app.use(express.json()); // ---------- SESSION BASED ---------- const redisClient = redis.createClient({ url: 'redis://localhost:6379' }); redisClient.connect().catch(console.error); app.use( session({ store: new RedisStore({ client: redisClient }), secret: 's3cr3t-s3ss10n', resave: false, saveUninitialized: false, cookie: { httpOnly: true, secure: false, maxAge: 24 * 60 * 60 * 1000 }, // 1 hari }) ); app.post('/login/session', async (req, res) => { const { email, password } = req.body; const user = await verifyPassword(email, password); if (!user) return res.status(401).json({ msg: 'Invalid credentials' }); // Simpan user ID ke dalam session req.session.userId = user.id; return res.json({ msg: 'Login successful' }); }); app.get('/profile/session', (req, res) => { if (!req.session.userId) return res.status(401).json({ msg: 'Not authenticated' }); // Ambil data user dari DB atau cache res.json({ userId: req.session.userId, msg: 'Session based profile' }); }); // ---------- JWT BASED ---------- const JWT_SECRET = 'jwt-s3cr3t-key'; const JWT_EXPIRES_IN = '1h'; app.post('/login/jwt', async (req, res) => { const { email, password } = req.body; const user = await verifyPassword(email, password); if (!user) return res.status(401).json({ msg: 'Invalid credentials' }); const token = jwt.sign( { sub: user.id, role: user.role }, // payload JWT_SECRET, { expiresIn: JWT_EXPIRES_IN } ); return res.json({ token }); }); function authenticateJWT(req, res, next) { const auth = req.headers.authorization; if (!auth || !auth.startsWith('Bearer ')) return res.status(401).json({ msg: 'Missing or malformed token' }); const token = auth.slice(7); jwt.verify(token, JWT_SECRET, (err, payload) => { if (err) return res.status(401).json({ msg: 'Invalid or expired token' }); req.user = payload; // { sub, role, iat, exp } next(); }); } app.get('/profile/jwt', authenticateJWT, (req, res) => { // Tidak perlu menyimpan apa-apa di server, cukup gunakan req.user res.json({ userId: req.user.sub, role: req.user.role, msg: 'JWT based profile' }); }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Catatan:
- Untuk produksi, gunakan pada cookie, gunakan HTTPS, dan simpan rahasia (code
secure: true,codesecret) di variabel lingkungan.codeJWT_SECRET - Jika ingin membatalkan JWT sebelum masa berlaku, pertimbangkan menyimpan daftar token yang telah di‑revoke (misal: di Redis) dan memerikשיה בכל request.
Kesimpulan
Pemilihan antara JWT dan Session tergantung pada arsitektur aplikasi dan kebutuhan operasional Anda:
- Session lebih cocok bila Anda ingin mengelola logout dengan mudah, memiliki sedikit instance server, dan tidak ingin menambah beban payload pada setiap request.
- JWT unggul dalam sistem terdistribusi, mikro‑layanan, atau situasi di mana stateless dan skalabilitas adalah prioritas utama, asalkan Anda siap menangani masa berlaku token dan mekanisme pencabutan bila diperlukan.
Kedua pendekatan aman bila diimplementasikan dengan benar—gunakan kunci kriptografi yang kuat, selalu sertakan flag
HttpOnlySecure*This blog is generated by n8n*