Session dễ revoke nhưng cần Redis khi chạy nhiều server; JWT stateless nên dễ scale nhưng không revoke được trước khi hết hạn.
Session-based: server giữ session data trong memory/Redis, client chỉ giữ session ID trong cookie. Server stateful nên phải lookup mỗi request.
- Được: revoke tức thì (xoá session), không lộ data người dùng ra client, server kiểm soát hoàn toàn.
- Mất: cần shared session store (Redis) khi nhiều server, horizontal scaling phức tạp hơn.
JWT: server stateless, client giữ toàn bộ claims trong token, verify chỉ cần kiểm chữ ký chứ không cần truy DB.
- Được: dễ scale, microservice verify được token mà không cần auth service tập trung.
- Mất: không revoke được trước hạn (muốn revoke phải có blacklist, tức là lại stateful), token nặng hơn session ID nhiều.
Chọn cái nào:
- Dùng session khi cần revoke tức thì (admin ban user, đổi mật khẩu phải huỷ hết session), khi chạy một server hoặc đã sẵn Redis, hoặc web app truyền thống đăng nhập bằng form.
- Dùng JWT khi làm microservice (auth giữa các service), API công khai cho mobile, SSO nhiều domain, hoặc bắt buộc kiến trúc stateless.
- Hybrid là best practice: JWT ngắn hạn (15 phút) cho access token, refresh token thì lưu server-side.
Lưu trữ token ở SPA: access token để trong memory (biến JS, không persist qua refresh — an toàn nhất), refresh token để trong httpOnly cookie cho JS không đọc được. ĐỪNG lưu token vào localStorage vì XSS lấy được.
Lưu ý: JWT không phải mã hoá — payload chỉ là base64, ai cầm token cũng đọc được claims, nên đừng nhét dữ liệu nhạy cảm vào đó.