48 Menyimpan dan Mengecek Token JWT
JSON Web Token (JWT) telah menjadi standar de facto dalam otentikasi modern, terutama untuk aplikasi berbasis web dan mobile. Penggunaan JWT memungkinkan kita untuk membuat sistem otentikasi yang bersifat stateless, sehingga server tidak perlu lagi menyimpan sesi (session) pengguna di backend. Namun, masih banyak pertanyaan mendasar di kalangan engineer, khususnya tentang tempat menyimpan token JWT dan cara mengeceknya secara aman. Artikel ini akan membahas tuntas dua aspek kunci tersebut: menyimpan dan memvalidasi JWT, lengkap dengan contoh kode, simulasi arsitektur sederhana, serta beberapa best practices yang patut diikuti.
Apa Itu JWT?
Secara sederhana, JWT adalah string berformat khusus yang terdiri dari tiga bagian utama:
- Header
- Payload
- Signature
JWT dikirimkan ke client setelah user berhasil login, lalu dikirim ulang ke server di setiap request yang membutuhkan otorisasi. JWT tidak hanya efisien, namun juga portable—bisa dibawa di mana saja, kapan saja.
Contoh token JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsIm5hbWUiOiJKb2huIERvZSJ9.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Bagian 1: Menyimpan Token JWT di Client
Penyimpanan token JWT di sisi client bisa menjadi pedang bermata dua. Pilihan penyimpanan yang salah dapat menimbulkan celah keamanan seperti XSS dan CSRF. Ada beberapa opsi utama:
Metode | Kelebihan | Kekurangan |
---|---|---|
Local Storage | Implementasi mudah, akses luas | Rentan XSS |
Session Storage | Seperti localStorage, tapi session-based | Rentan XSS, hilang saat tab ditutup |
Cookie (HTTPOnly) | Tidak bisa diakses JS, aman dari XSS | Rentan CSRF jika tanpa SameSite |
Tabel 1: Perbandingan tempat penyimpanan token JWT
Simulasi Penyimpanan JWT di Local Storage
// Setelah login sukses
localStorage.setItem('access_token', jwtToken);
// Mengambil token pada request selanjutnya
const token = localStorage.getItem('access_token');
fetch('/api/resource', {
headers: {
'Authorization': `Bearer ${token}`
}
});
Namun, localStorage sangat rentan terhadap serangan XSS. Jika attacker bisa menanamkan skrip jahat dalam aplikasi, token bisa dicuri dengan mudah.
Penyimpanan dengan HTTPOnly Cookie
Cara terbaik untuk kebutuhan keamanan lebih tinggi adalah dengan menyimpan JWT di cookie yang diberi flag HttpOnly
dan SameSite
.
// Server mengirimkan set-cookie header saat login
Set-Cookie: token=eyJhbGc...; HttpOnly; Secure; SameSite=Strict
Dengan cara ini, token tidak dapat diakses dari JavaScript, sehingga serangan XSS tidak bisa mengambilnya.
Pro Tips:
- Gunakan
SameSite=Strict
jika aplikasi tidak perlu berbagi cookie lintas domain. - Tambahkan
Secure
agar cookie hanya terkirim melalui HTTPS.
Bagian 2: Mengecek/Memvalidasi Token JWT di Server
Setelah token JWT disimpan di client, langkah selanjutnya adalah mengecek validitas setiap request yang masuk. Umumnya, proses ini dilakukan dengan middleware di backend. Mari kita bahas pada dua stack: Node.js (Express) dan Go (Golang).
2.1 Cek Token JWT di Node.js/Express
Untuk verifikasi JWT di Express, kita akan memakai library jsonwebtoken
.
Middleware Express: authenticateJWT.js
const jwt = require('jsonwebtoken');
function authenticateJWT(req, res, next) {
const authHeader = req.headers.authorization;
if (authHeader) {
// Format: "Bearer <token>"
const token = authHeader.split(' ')[1];
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) {
return res.sendStatus(403); // Forbidden
}
req.user = user;
next();
});
} else {
res.sendStatus(401); // Unauthorized
}
}
module.exports = authenticateJWT;
Penggunaan Middleware
const express = require('express');
const authenticateJWT = require('./authenticateJWT');
const app = express();
app.get('/api/resource', authenticateJWT, (req, res) => {
res.json({ message: "Hello, " + req.user.name });
});
2.2 Verifikasi JWT di Golang
Di Golang, biasanya kita menggunakan package github.com/golang-jwt/jwt/v4
.
import (
"github.com/golang-jwt/jwt/v4"
"net/http"
"strings"
)
var secretKey = []byte("your-secret-key")
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
http.Error(w, "missing auth header", http.StatusUnauthorized)
return
}
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return secretKey, nil
})
if err != nil || !token.Valid {
http.Error(w, "invalid token", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
Diagram Alur: Proses Validasi JWT
Mari kita ilustrasikan secara visual alur penyimpanan dan pengecekan token JWT.
sequenceDiagram participant Client participant Server Client->>Server: Login (username, password) Server-->>Client: JWT Token (response body / Set-Cookie) Note over Client: Simpan token (localStorage/cookie) Client->>Server: Request API (Authorization: Bearer) Server->>Server: Verifikasi JWT (cek signature & expired) alt Valid Server-->>Client: Data/Respon Success else Tidak Valid Server-->>Client: 401/403 Error end
Studi Kasus: Client Local Storage VS Cookies
Skenario | localStorage | Cookies (HTTPOnly) |
---|---|---|
Dapat dicuri via XSS | Ya | Tidak |
Dapat digunakan untuk CSRF | Tidak (umumnya) | Ya (jika tanpa SameSite=Strict) |
Dapat diakses JavaScript | Ya | Tidak |
Implementasi Safari/Android | Konsisten | Kadang masalah di CORS dan domain/subdomain |
Best Practices
- Gunakan Cookie HTTPOnly jika aplikasi sangat mementingkan keamanan.
- Tambahkan mekanisme refresh token terpisah, bukan bagian dari JWT utama.
- Pastikan library JWT di server selalu update.
- Selalu validasi exp (expired field) pada payload JWT.
- Tidak menyimpan data sensitif di payload.
- Lakukan revoke dengan menyimpan daftar blacklist di server (opsional, jika perlu session revoke).
Kesimpulan
Menyimpan dan mengecek token JWT bukan sekadar implementasi teknis, namun juga keputusan arsitektural yang sangat mempengaruhi keamanan aplikasi.
Sebelum memilih metode penyimpanan, pahami trade-off antara kemudahan (developer experience) dan keamanan (security risk). Untuk aplikasi skala kecil-menengah, localStorage sering jadi pilihan praktis, tapi untuk aplikasi finansial atau data sensitif, cookie dengan HttpOnly adalah pilihan mutlak.
Selalu evaluasi kembali security landscape aplikasi Anda secara berkala, dan jangan ragu untuk mengadopsi best practices terbaru di dunia otentikasi JWT. Happy coding!
Artikel Terhangat
48 Menyimpan dan Mengecek Token JWT
08 Aug 2025
47 Membuat Mutation Login dan Signup
08 Aug 2025
69. Studi Kasus: Retry dan Backoff Strategy
08 Aug 2025
46 Menambahkan Middleware Autentikasi JWT
08 Aug 2025
68. Kompresi Data (gzip) di gRPC
08 Aug 2025
67. Retry Mechanism di Client gRPC
08 Aug 2025

48 Menyimpan dan Mengecek Token JWT

47 Membuat Mutation Login dan Signup

69. Studi Kasus: Retry dan Backoff Strategy

46 Menambahkan Middleware Autentikasi JWT

68. Kompresi Data (gzip) di gRPC
