JWT (JSON Web Token) adalah standar terbuka (RFC 7519) untuk mentransmisikan informasi antar pihak secara aman dalam bentuk JSON object yang di-sign secara digital.
Struktur JWT: JWT terdiri dari 3 bagian yang dipisahkan titik:
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjQyLCJyb2xlIjoiYWRtaW4ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
└───────┬────────────┘.└──────────────┬───────────────────┘.└──────────────┬──────────────┘
Header Payload Signature
1. Header — algoritma dan tipe token:
{ "alg": "HS256", "typ": "JWT" }
2. Payload — data (claims):
{
"userId": 42,
"role": "admin",
"iat": 1700000000,
"exp": 1700086400
}
Claims standar:
iss(issuer) — siapa yang membuat tokensub(subject) — siapa yang di-identifikasiexp(expiration) — kapan token kadaluarsaiat(issued at) — kapan token dibuatjti(JWT ID) — ID unik token
3. Signature — memastikan token tidak dimanipulasi:
HMACSHA256(base64(header) + "." + base64(payload), secret)
Alur JWT authentication:
1. POST /login { email, password }
2. Server verifikasi → buat JWT → kirim ke client
3. Client simpan JWT (biasanya di memory atau cookie)
4. Client kirim JWT di setiap request:
Authorization: Bearer eyJhbGci...
5. Server verifikasi signature → baca payload → proses request
Implementasi:
const jwt = require("jsonwebtoken");
const SECRET = process.env.JWT_SECRET; // HARUS rahasia dan random!
// Membuat token (saat login):
function generateToken(user) {
return jwt.sign(
{ userId: user.id, role: user.role },
SECRET,
{ expiresIn: "15m" } // token pendek untuk keamanan
);
}
// Memverifikasi token (middleware):
function verifyToken(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith("Bearer ")) {
return res.status(401).json({ error: "Token tidak ditemukan" });
}
const token = authHeader.split(" ")[1];
try {
const decoded = jwt.verify(token, SECRET);
req.user = decoded; // { userId: 42, role: "admin" }
next();
} catch (err) {
if (err.name === "TokenExpiredError") {
return res.status(401).json({ error: "Token kadaluarsa" });
}
return res.status(401).json({ error: "Token tidak valid" });
}
}
JWT vs Session:
| Aspek | JWT | Session |
|---|---|---|
| State | Stateless (di client) | Stateful (di server) |
| Scalability | Mudah scale | Butuh shared storage |
| Revocation | Sulit (butuh blacklist) | Mudah (hapus session) |
| Payload | Bisa bawa data | Hanya session ID |
| Ukuran | Lebih besar | Kecil (hanya ID) |
PENTING — Kelemahan JWT:
- Tidak bisa di-revoke tanpa mekanisme tambahan (blacklist/whitelist)
- Payload bisa di-decode siapa saja (hanya di-sign, BUKAN dienkripsi)
- Jangan simpan data sensitif di payload
- Jika disimpan di localStorage, rentan XSS — pertimbangkan HttpOnly cookie