JWT vs Session: 5 Perbedaan dan Mana yang Harus Dipakai

JWT vs Session adalah pertanyaan yang hampir selalu muncul saat kamu membangun fitur login. Kamu baru selesai membuat endpoint register, lalu bingung: setelah user berhasil login, data apa yang disimpan dan di mana? Dua jawaban paling populer adalah session dan JSON Web Token (JWT).

Keduanya sama-sama bertujuan mengenali user di request berikutnya, tetapi cara kerjanya berbeda jauh. Pilihan yang salah bisa membuat aplikasi sulit di-scale, rawan dibobol, atau merepotkan saat user perlu logout. Di artikel ini kita bahas JWT vs Session secara praktis, lengkap dengan contoh kode di Express.

[GAMBAR 1 di sini] Alt text: diagram perbandingan JWT vs Session pada autentikasi aplikasi web

[Sisipkan blok Table of Contents Rank Math di sini]

Apa Itu Session dan JWT?

Sebelum masuk ke perbandingan JWT vs Session, kita samakan dulu pemahaman dasarnya. HTTP itu stateless, artinya server tidak otomatis ingat siapa kamu di request sebelumnya. Autentikasi menyelesaikan masalah ini dengan cara memberi “tanda pengenal” ke user setelah login.

Cara Kerja Session

Pada autentikasi berbasis session, server menyimpan data login user di sisi server. Alurnya seperti ini:

  1. User mengirim email dan password.
  2. Server memverifikasi, lalu membuat session dan menyimpannya di memori, database, atau Redis.
  3. Server mengirim session ID ke browser lewat cookie.
  4. Di setiap request berikutnya, browser otomatis mengirim cookie itu, dan server mencari data session yang cocok.

Session ID hanyalah kode acak. Data aslinya, seperti ID user dan role, tetap tersimpan di server.

Cara Kerja JWT

JSON Web Token adalah token yang berisi data user dan ditandatangani secara digital. Formatnya terdiri dari tiga bagian yang dipisah titik: header, payload, dan signature. Spesifikasinya dijelaskan di RFC 7519.

Alurnya:

  1. User mengirim email dan password.
  2. Server memverifikasi, lalu membuat token yang ditandatangani dengan secret key.
  3. Token dikirim ke client, dan client menyimpannya.
  4. Di setiap request, client mengirim token itu, biasanya lewat header Authorization: Bearer <token>.
  5. Server memverifikasi tanda tangan token tanpa perlu mencari data di database.

Satu hal penting: payload JWT hanya di-encode, bukan dienkripsi. Siapa pun yang memegang token bisa membaca isinya. Tanda tangan hanya menjamin isinya tidak diubah.

5 Perbedaan JWT vs Session

Berikut perbedaan JWT vs Session yang paling berpengaruh saat kamu mengambil keputusan.

1. Tempat Penyimpanan State

Pada session, state disimpan di server. Client hanya memegang session ID. Pada JWT, state ada di dalam token yang dipegang client, sehingga server tidak perlu menyimpan apa pun.

Inilah akar dari semua perbedaan lainnya. Session bersifat stateful, sedangkan JWT bersifat stateless.

2. Skalabilitas

Dalam urusan skalabilitas, JWT vs Session menghasilkan trade-off yang jelas. Dengan session, setiap server harus bisa mengakses data session yang sama. Jika aplikasimu berjalan di beberapa server, kamu butuh penyimpanan bersama seperti Redis, atau sticky session di load balancer.

JWT lebih mudah di-scale karena server cukup memverifikasi tanda tangan. Cocok untuk arsitektur microservices, ketika beberapa layanan perlu memverifikasi identitas user tanpa berbagi database session.

3. Logout dan Pencabutan Akses

Di sinilah session unggul. Untuk memaksa user logout, kamu tinggal menghapus session di server, dan akses langsung berhenti saat itu juga.

JWT lebih rumit. Token yang sudah diterbitkan tetap valid sampai masa berlakunya habis, walaupun user sudah “logout” di aplikasi. Untuk mencabut akses lebih awal, kamu perlu mekanisme tambahan seperti denylist token atau versi token di database, dan ini mengurangi sifat stateless-nya.

4. Keamanan

Dalam keamanan, JWT vs Session sama-sama bisa aman atau berbahaya, tergantung cara pemakaiannya.

  • Session dengan cookie rentan terhadap serangan CSRF karena browser mengirim cookie otomatis. Atur atribut SameSite, dan gunakan token CSRF bila perlu.
  • JWT yang disimpan di localStorage bisa dicuri lewat serangan XSS. Menyimpannya di cookie HttpOnly mengurangi risiko ini, tetapi membawa kembali isu CSRF.

Apa pun pilihanmu, gunakan HTTPS dan ikuti panduan dari OWASP Session Management Cheat Sheet.

5. Ukuran Data dan Performa Request

Session ID hanya berupa string pendek. JWT berukuran lebih besar karena membawa payload dan tanda tangan, dan token ini ikut terkirim di setiap request. Semakin banyak data yang kamu masukkan, semakin besar beban header-nya.

Sebaliknya, JWT menghemat query ke penyimpanan session. Jadi pilihan ini bergantung pada mana yang lebih mahal di sistemmu: bandwidth atau lookup data.

Tabel Perbandingan JWT vs Session

AspekSessionJWT
Penyimpanan stateDi serverDi dalam token (client)
SifatStatefulStateless
SkalabilitasButuh penyimpanan bersamaLebih mudah di-scale
Logout / cabut aksesInstanSulit sebelum token kedaluwarsa
Ukuran per requestKecil (session ID)Lebih besar
Risiko utamaCSRFXSS (jika di localStorage)
Cocok untukWeb app monolitik dan server-renderedAPI, mobile app, microservices

Contoh Kode Session di Express

Berikut contoh sederhana autentikasi session memakai express-session. Untuk produksi, ganti penyimpanan bawaan dengan Redis atau database.

javascript

const express = require('express');
const session = require('express-session');

const app = express();
app.use(express.json());

app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    secure: true,      // wajib HTTPS di produksi
    sameSite: 'lax',
    maxAge: 1000 * 60 * 60 // 1 jam
  }
}));

app.post('/login', async (req, res) => {
  const user = await verifyUser(req.body.email, req.body.password);
  if (!user) return res.status(401).json({ message: 'Email atau password salah' });

  req.session.userId = user.id;
  res.json({ message: 'Login berhasil' });
});

app.get('/profile', (req, res) => {
  if (!req.session.userId) {
    return res.status(401).json({ message: 'Belum login' });
  }
  res.json({ userId: req.session.userId });
});

app.post('/logout', (req, res) => {
  req.session.destroy(() => res.json({ message: 'Logout berhasil' }));
});

Perhatikan bahwa secret diambil dari environment variable. Kalau kamu belum terbiasa, baca panduan environment variable di Node.js agar kunci rahasia tidak ikut ter-commit.

Contoh Kode JWT di Express

Sekarang versi JWT memakai paket jsonwebtoken. Token berumur pendek agar risiko berkurang jika bocor.

javascript

const jwt = require('jsonwebtoken');

app.post('/login', async (req, res) => {
  const user = await verifyUser(req.body.email, req.body.password);
  if (!user) return res.status(401).json({ message: 'Email atau password salah' });

  const token = jwt.sign(
    { sub: user.id, role: user.role },
    process.env.JWT_SECRET,
    { expiresIn: '15m' }
  );
  res.json({ token });
});

function auth(req, res, next) {
  const header = req.headers.authorization || '';
  const token = header.split(' ')[1];
  if (!token) return res.status(401).json({ message: 'Token tidak ada' });

  try {
    req.user = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ['HS256'] });
    next();
  } catch (err) {
    res.status(401).json({ message: 'Token tidak valid atau kedaluwarsa' });
  }
}

app.get('/profile', auth, (req, res) => {
  res.json({ userId: req.user.sub, role: req.user.role });
});

Dua detail yang sering terlewat: selalu batasi algorithms saat verifikasi, dan jangan memasukkan data sensitif seperti password ke payload.

[GAMBAR 2 di sini, misalnya cuplikan kode atau alur login] Alt text: contoh kode autentikasi JWT vs Session di Express

Kalau frontend-mu berada di domain berbeda dan request ditolak browser, kemungkinan kamu butuh membaca cara mengatasi CORS error di Express, terutama saat memakai cookie lintas domain.

Kapan Sebaiknya Memilih Session?

Pada JWT vs Session, session adalah pilihan yang masuk akal jika:

  • Aplikasimu berupa web app monolitik atau server-rendered.
  • Kamu butuh kontrol penuh, misalnya mengeluarkan user dari semua perangkat dengan cepat.
  • Kamu ingin cara yang sederhana dan sudah teruji untuk autentikasi browser.
  • Data login tidak perlu dibagikan ke banyak layanan terpisah.

Untuk proyek pemula atau aplikasi internal, session sering menjadi pilihan paling aman dan paling mudah dipahami.

Kapan Sebaiknya Memilih JWT?

Di sisi lain, JWT lebih cocok jika:

  • Kamu membangun REST API yang dipakai oleh mobile app dan web sekaligus.
  • Arsitekturnya microservices, dan beberapa layanan perlu memverifikasi identitas user secara mandiri.
  • Kamu membutuhkan autentikasi lintas domain atau lintas platform.
  • Kamu siap mengelola refresh token untuk masa berlaku yang pendek.

Kalau kamu masih menimbang gaya API-nya, baca juga perbandingan REST API vs GraphQL karena keputusan ini ikut memengaruhi cara kamu mengirim token.

Cara Memilih JWT vs Session dengan 4 Pertanyaan

Kalau masih ragu, jawab empat pertanyaan berikut. Hasilnya biasanya langsung mengarah ke satu pilihan.

1. Siapa kliennya? Jika hanya browser pada satu domain, session sudah cukup dan sangat nyaman. Jika kliennya campuran, seperti web, aplikasi mobile, dan layanan pihak ketiga, JWT lebih fleksibel.

2. Berapa server yang kamu jalankan? Satu server membuat session sangat mudah. Banyak server tanpa penyimpanan bersama membuat JWT lebih menarik, atau kamu perlu menyiapkan Redis untuk session.

3. Seberapa cepat akses harus bisa dicabut? Kalau jawabannya “seketika”, pilih session atau gabungkan JWT berumur pendek dengan refresh token yang bisa dihapus. Jika masa berlaku 15 menit masih dapat diterima, JWT murni sudah memadai.

4. Seberapa besar tim dan pengalamanmu? Session punya lebih sedikit bagian yang bergerak. JWT menuntut kamu mengelola kedaluwarsa, rotasi kunci, dan refresh token dengan benar. Untuk tim kecil, kesederhanaan sering lebih berharga daripada fleksibilitas.

Hasil dari empat pertanyaan itu adalah dasar keputusan JWT vs Session yang lebih jujur dibanding sekadar mengikuti tren. Ingat juga bahwa keputusan ini tidak permanen. Banyak aplikasi mulai dari session, lalu berpindah ke JWT atau pola gabungan setelah arsitekturnya berkembang. Selama logika autentikasi kamu pisahkan rapi dalam satu modul, migrasi tidak harus menyakitkan.

Studi Kasus: Memilih JWT vs Session untuk 4 Jenis Proyek

Teori akan lebih mudah dipahami lewat contoh nyata. Berikut cara memikirkan JWT vs Session pada empat jenis proyek yang umum.

Website dengan panel admin. Misalnya blog, toko kecil, atau company profile yang dirender di server dan berjalan di satu server. Session paling masuk akal di sini. Alurnya sederhana, browser mengelola cookie otomatis, dan kamu bisa mengeluarkan admin kapan saja dengan menghapus session-nya.

Aplikasi mobile dengan backend REST API. Aplikasi mobile tidak mengelola cookie semudah browser, sehingga JWT sebagai access token biasanya lebih praktis. Simpan token di penyimpanan aman milik platform, seperti Keychain di iOS atau Keystore di Android, dan pakai refresh token agar user tidak perlu login berulang.

Platform dengan banyak layanan (microservices). Bayangkan marketplace dengan layanan pesanan, pembayaran, dan notifikasi yang terpisah. Jika semuanya harus mengecek session ke satu penyimpanan, layanan itu menjadi titik macet. Dengan JWT, setiap layanan cukup memverifikasi tanda tangan token, sehingga beban terdistribusi lebih merata. Pada kasus ini JWT vs Session condong ke JWT.

Dashboard internal perusahaan. Pengguna terbatas, data sensitif, dan tim keamanan sering meminta kemampuan mencabut akses seketika saat karyawan keluar. Session lebih unggul karena kontrolnya terpusat dan efeknya langsung terasa.

Dari keempat contoh itu terlihat polanya: semakin terdistribusi arsitekturmu, semakin menarik JWT. Semakin terpusat dan butuh kontrol ketat, semakin kuat alasan memakai session.

Cara Menguji Autentikasi Sebelum Rilis

Memilih JWT vs Session baru setengah pekerjaan. Setengah lainnya adalah memastikan implementasinya benar. Sebelum rilis, coba skenario berikut.

  1. Akses endpoint terlindungi tanpa login. Server harus menjawab status 401.
  2. Pakai token palsu atau diubah. Ubah satu karakter pada payload JWT, lalu kirim lagi. Verifikasi harus gagal.
  3. Pakai token yang sudah kedaluwarsa. Pastikan server menolaknya dan tidak mengembalikan data.
  4. Logout, lalu pakai session ID lama. Pada session, permintaan itu harus ditolak.
  5. Periksa atribut cookie. Buka DevTools, tab Application, lalu pastikan HttpOnly, Secure, dan SameSite sudah aktif.
  6. Coba login berulang dengan password salah. Pastikan ada pembatasan percobaan.

Kamu bisa memeriksa dua skenario pertama lewat terminal:

bash

# tanpa kredensial, harus 401
curl -i http://localhost:3000/profile

# dengan token palsu, harus 401
curl -i http://localhost:3000/profile \
  -H "Authorization: Bearer TOKEN_PALSU"

Biasakan menulis tes otomatis untuk skenario ini. Satu perubahan kecil pada middleware autentikasi bisa membuka celah tanpa disadari, dan tes otomatis akan menangkapnya lebih awal.

Pola Gabungan: Access Token dan Refresh Token

Banyak aplikasi tidak memilih salah satu secara ekstrem. Pola yang umum adalah:

  • Access token JWT berumur pendek, misalnya 15 menit, untuk mengakses API.
  • Refresh token berumur panjang, disimpan di server (database) dan dikirim lewat cookie HttpOnly, untuk meminta access token baru.

Dengan pola ini, kamu mendapat kemudahan JWT sekaligus kemampuan mencabut akses, karena refresh token bisa dihapus dari server kapan saja. Dalam praktik, ini adalah jalan tengah terbaik dari perdebatan JWT vs Session.

Kesalahan Umum Saat Memakai JWT vs Session

Beberapa kesalahan yang sering terjadi:

  • Menyimpan data sensitif di payload JWT. Payload bisa dibaca siapa saja.
  • Membuat JWT tanpa masa kedaluwarsa. Token yang bocor akan berlaku selamanya.
  • Menyimpan token di localStorage tanpa memahami risiko XSS.
  • Memakai MemoryStore bawaan express-session di produksi. Ini tidak dirancang untuk produksi dan data hilang saat server restart.
  • Mengabaikan atribut cookie seperti HttpOnly, Secure, dan SameSite.
  • Tidak memberi pembatasan percobaan login. Tambahkan rate limiting pada backend agar endpoint login tidak mudah ditebak dengan brute force.
  • Memilih JWT hanya karena terlihat modern. Teknologi baru belum tentu lebih cocok untuk kebutuhanmu.

Best Practice Autentikasi untuk Pemula

Apa pun hasil pilihan JWT vs Session, terapkan hal-hal berikut:

  1. Selalu pakai HTTPS di semua environment selain lokal.
  2. Hash password dengan algoritma yang aman seperti bcrypt atau argon2, jangan simpan password asli.
  3. Simpan secret di environment variable, bukan di dalam kode.
  4. Batasi masa berlaku token dan session.
  5. Gunakan cookie HttpOnly untuk menyimpan kredensial bila memungkinkan.
  6. Validasi semua input dan catat percobaan login yang gagal.
  7. Rotasi secret secara berkala dan siapkan rencana jika kunci bocor.

Kalau kamu masih di tahap awal belajar backend, ikuti dulu roadmap belajar ngoding untuk pemula agar fondasi HTTP dan database-nya kuat sebelum masuk ke autentikasi.

Kesimpulan

Perbedaan JWT vs Session terletak pada tempat penyimpanan state, skalabilitas, kemudahan mencabut akses, risiko keamanan, dan ukuran request. Session unggul dalam kontrol dan kesederhanaan untuk aplikasi web biasa, sedangkan JWT unggul untuk API, mobile app, dan arsitektur terdistribusi.

Tidak ada jawaban tunggal yang benar untuk semua kasus. Mulailah dari kebutuhan: jenis aplikasimu, jumlah server, dan seberapa cepat kamu perlu mencabut akses. Setelah itu pilih pendekatan yang paling sederhana yang memenuhi kebutuhan tersebut, lalu terapkan praktik keamanan dasarnya dengan disiplin.

Dengan memahami JWT vs Session, kamu bisa membangun fitur login yang aman, mudah dirawat, dan siap berkembang.

Leave a Reply

Your email address will not be published. Required fields are marked *