Tại sao bạn nên ngừng sử dụng JWT để quản lý phiên đăng nhập?
JWT không được thiết kế để duy trì trạng thái đăng nhập của người dùng và không thực sự an toàn cho mục đích này. Bài viết lập luận rằng cookie phiên (session cookies) là giải pháp tốt hơn, hiệu quả và an toàn hơn nhiều so với JWT trong hầu hết các trường hợp xác thực web.

JWT (JSON Web Tokens) đang rất phổ biến trong cộng đồng phát triển web, nhưng việc sử dụng chúng để duy trì trạng thái đăng nhập của người dùng thực chất là một sai lầm phổ biến. JWT không được thiết kế cho mục đích này, chúng thiếu tính bảo mật cần thiết và thực tế đã có một công cụ tốt hơn được thiết kế riêng cho việc này: cookie phiên (session cookies).
Vấn đề cốt lõi của JWT
Lý do chính để tránh sử dụng JWT cho các phiên làm việc (sessions) xoay quanh một số điểm kỹ thuật quan trọng:
- Thời gian tồn tại ngắn: Đặc tả kỹ thuật của JWT được thiết kế cụ thể cho các token có thời gian sống rất ngắn (khoảng 5 phút hoặc ít hơn). Tuy nhiên, các phiên đăng nhập của người dùng thường cần thời gian tồn tại dài hơn nhiều để đảm bảo trải nghiệm sử dụng.
- Huyền thoại về "Stateless": Xác thực không trạng thái (stateless) thực sự không khả thi theo một cách bảo mật. Bạn bắt buộc phải có một số trạng thái để xử lý việc thu hồi token một cách an toàn. Nếu bạn bắt buộc phải có một kho lưu trữ dữ liệu (data store) để kiểm tra token, thì tốt hơn là nên lưu trữ toàn bộ dữ liệu phiên đó thay vì chỉ lưu một ID token.
- Hiệu suất thấp: Các JWT chỉ lưu trữ một token phiên đơn giản thì kém hiệu quả và kém linh hoạt hơn so với cookie phiên thông thường, đồng thời không mang lại bất kỳ lợi thế thực tế nào.
Đặc tả JWT không đáng tin cậy về mặt bảo mật
Bản thân đặc tả JWT không được các chuyên gia bảo mật tin tưởng. Điều này đủ để loại trừ việc sử dụng chúng cho bất kỳ thứ gì liên quan đến bảo mật và xác thực. Đặc tả ban đầu cụ thể đã tạo điều kiện cho việc tạo ra các token giả mạo (ví dụ: qua tấn công nhầm lẫn thuật toán) và có khả năng chứa các lỗi thiết kế khác.
Phản biện các quan điểm ủng hộ JWT
Nhiều người lập luận rằng Google sử dụng JWT. Tuy nhiên, Google không sử dụng JWT cho các phiên người dùng trên trình duyệt. Họ sử dụng cookie phiên thông thường. JWT chỉ được sử dụng làm phương thức vận chuyển cho Đăng nhập một lần (SSO) để phiên đăng nhập của bạn trên một máy chủ có thể được chuyển sang một máy chủ khác. Đây là trường hợp sử dụng hợp lý, và Google có nguồn lực (các chuyên gia bảo mật hàng đầu) để tạo và duy trì việc triển khai JWT an toàn hơn.
Về quan điểm "stateless là tốt hơn", bạn không thể có xác thực thực sự không trạng thái một cách an toàn mà không có nguồn lực khổng lồ. Hơn nữa, khái niệm "Stateless" trong bối cảnh này thực chất là một sự ngụy biện.
Giải pháp thay thế: Session và PASETO
Nếu bạn không biết cách thiết lập phiên, đừng lo lắng. Hầu hết mọi khung web (web framework) đều chứa triển khai cho các phiên, và thường rất dễ để bật chúng nếu chúng không được bật theo mặc định. Ví dụ, với Express trong Node.js, bạn chỉ cần sử dụng middleware express-session và một bộ kết nối lưu trữ (store connector) hoạt động với cơ sở dữ liệu của bạn (ví dụ: connect-session-knex để sử dụng với Postgres, MySQL hoặc SQLite).
Nếu bạn thực sự cần một token có chữ ký ngắn hạn cho một mục đích cụ thể khác, có một đặc tả tốt hơn gọi là PASETO được thiết kế để đảm bảo tính bảo mật. Chỉ cần đảm bảo rằng bạn không sử dụng chúng cho các phiên đăng nhập của người dùng.


