JWT (JSON Web Token)
1. Tổng quan
A. Khái niệm
JWT là token chứa thông tin (Claims) cần cho xác thực·phân quyền dưới dạng JSON và được ký số, là token tiêu chuẩn (RFC 7519) cho phép máy chủ xác thực người dùng mà không cần lưu phiên (phi trạng thái, Stateless). Ba phần được phân tách bằng dấu chấm (.) được mã hóa Base64URL và biểu diễn thành một chuỗi duy nhất (
xxxxx.yyyyy.zzzzz).
Lý do căn bản khiến JWT được sử dụng rộng rãi là "giúp máy chủ không cần ghi nhớ trạng thái đăng nhập". Để hiểu bối cảnh của ý tưởng này, trước hết cần chỉ ra gánh nặng cấu trúc của phương thức phiên truyền thống. Trong phương thức phiên, khi người dùng đăng nhập, máy chủ cấp một định danh phiên (Session ID) và lưu trạng thái thực của phiên đó (ID người dùng·quyền·thời điểm đăng nhập v.v.) trong bộ nhớ máy chủ, DB hoặc kho phiên riêng. Sau đó, với mỗi yêu cầu, máy chủ tra cứu kho bằng Session ID do máy khách gửi đến để xác nhận người dùng. Tức là "nguồn chân lý (Source of Truth)" nằm ở kho phía máy chủ.
Cấu trúc này không có vấn đề trên một máy chủ đơn, nhưng trong môi trường phân tán·đám mây có nhiều máy chủ thì lập tức trở thành nút thắt cổ chai. Vì không biết yêu cầu sẽ được định tuyến tới máy chủ nào, mọi máy chủ phải nhìn thấy cùng một phiên; để làm vậy phải cố định vào một máy chủ cụ thể bằng phiên dính (Sticky Session), hoặc đặt kho phiên tập trung như Redis để chia sẻ. Cách thứ nhất cản trở cân bằng tải và triển khai không gián đoạn, cách thứ hai khiến kho trở thành điểm lỗi đơn (SPOF) và nút thắt hiệu năng. Khi lưu lượng lên tới hàng chục nghìn yêu cầu mỗi giây, bản thân việc tra cứu phiên ở mỗi yêu cầu đã là gánh nặng.
JWT đảo ngược ý tưởng này. Thông tin cần cho xác thực được đặt vào chính token và ký, rồi máy khách giữ token này và gửi kèm mỗi yêu cầu. Máy chủ chỉ cần xác minh chữ ký của token mà không phải tra cứu kho riêng. Nếu chữ ký hợp lệ thì tin tưởng nội dung token. Nhờ chuyển nguồn chân lý từ kho máy chủ sang chính token, máy chủ không còn giữ trạng thái (Stateless) và dù yêu cầu đến máy chủ nào thì chỉ cần xác minh. Vì vậy JWT rất phù hợp cho xác thực trong môi trường phân tán nơi máy chủ mở rộng theo chiều ngang như MSA·API gateway·di động·SPA. Tuy nhiên, tính tự chứa này đi kèm cái giá — đó là đặc tính máy chủ khó cưỡng chế vô hiệu hóa token đã cấp trước khi hết hạn, và sự đánh đổi này chi phối toàn bộ thiết kế sau đó.
B. Đặc điểm
Đặc điểm của JWT được tóm tắt thành bốn điểm. Thứ nhất, máy chủ phi trạng thái (Stateless) — máy chủ không lưu phiên nên dễ mở rộng ngang. Thứ hai, tính tự chứa (Self-contained) — thông tin cần cho xác minh nằm trong token nên được xử lý mà không cần tra cứu bên ngoài. Thứ ba, toàn vẹn dựa trên chữ ký (Integrity) — phát hiện giả mạo·sửa đổi bằng chữ ký, nhưng điểm cốt lõi là chữ ký không "che giấu nội dung (bảo mật)" mà "bảo đảm nội dung không bị thay đổi (toàn vẹn)". Thứ tư, tính khả chuyển (Portability) — dùng định dạng phổ quát JSON·Base64URL nên thông dụng vượt qua ngôn ngữ·nền tảng·miền. Các đặc điểm này đan xen: tính phi trạng thái sinh ra khả năng mở rộng, tính tự chứa khiến phi trạng thái khả thi, và cái giá là đồng thời sinh ra giới hạn khó vô hiệu hóa.
2. Cấu trúc và thành phần của JWT
JWT có cấu trúc gồm ba phần Header, Payload, Signature nối với nhau bằng dấu chấm (.). Dưới đây là sơ đồ cấu trúc tổng thể.
flowchart LR
subgraph JWT["Chuỗi JWT (xxxxx.yyyyy.zzzzz)"]
H["Header<br/>(kiểu typ, thuật toán alg)"]
P["Payload<br/>(Claims: thông tin·quyền·hạn dùng)"]
S["Signature<br/>(giá trị chữ ký)"]
end
H -.Base64URL.- P -.Base64URL.- S
SK["Khóa bí mật/khóa riêng của máy chủ"] --> S
style P fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px
style S fill:#fde8e8,stroke:#d64545,stroke-width:2px
A. Header (tiêu đề). Header chứa siêu dữ liệu của token. Các trường cốt lõi là typ biểu thị kiểu token (thường là JWT) và alg biểu thị thuật toán dùng để ký (ví dụ HS256, RS256). Header quan trọng vì bên xác minh đọc từ đây "phải xác minh bằng thuật toán nào". Chính điểm này cũng là khởi đầu của những lỗ hổng bảo mật nổi tiếng. Đã biết các tấn công trong đó kẻ tấn công đổi alg thành none (bỏ qua xác minh chữ ký), hoặc tráo phương thức bất đối xứng (RS256) thành đối xứng (HS256) để lạm dụng khóa công khai như khóa bí mật. Vì vậy trong thực tiễn, máy chủ không được tin nguyên alg trong header mà phải cố định thuật toán cho phép trong cấu hình máy chủ (Allowlist) để xác minh.
B. Payload (tải trọng) và Claims. Payload là tập hợp các claim — thông tin thực tế. Claim chia làm ba loại. Claim đăng ký (Registered) là các từ khóa dành riêng do tiêu chuẩn quy định, gồm iss (bên phát hành), sub (chủ thể), aud (đối tượng nhận), exp (thời điểm hết hạn), iat (thời điểm phát hành), nbf (thời điểm bắt đầu hiệu lực), jti (ID duy nhất của token). Claim công khai (Public) được đặt tên bằng URI v.v. để tránh xung đột, còn claim riêng (Private) là giá trị tự định nghĩa do bên phát hành và người dùng thỏa thuận (ví dụ role, dept). Nguyên tắc nhất định phải nhớ ở đây là payload chỉ được ký chứ không được mã hóa. Base64URL là mã hóa ký tự (encoding) chứ không phải mã hóa bảo mật (encryption), nên ai cũng có thể giải mã để đọc nội dung. Do đó tuyệt đối không được đưa vào thông tin nhạy cảm như mật khẩu·số định danh công dân·số thẻ; nếu buộc phải đưa vào thì phải mã hóa riêng bằng JWE (JSON Web Encryption).
C. Signature (chữ ký). Chữ ký được tạo với đầu vào Base64URL(Header) + "." + Base64URL(Payload) bằng khóa mà máy chủ nắm giữ. Phương thức khóa đối xứng (HS256) dùng một khóa bí mật cho cả ký và xác minh, còn phương thức khóa bất đối xứng (RS256·ES256) ký bằng khóa riêng và xác minh bằng khóa công khai. Vai trò của chữ ký là bảo đảm toàn vẹn — chỉ cần thay đổi một ký tự trong payload là chữ ký lệch và xác minh thất bại. Vì vậy quản lý khóa ký là tử huyệt của bảo mật JWT. Với HS256, nếu khóa bí mật bị lộ, kẻ tấn công có thể giả mạo token tùy ý, và nếu khóa ngắn sẽ bị phá bằng vét cạn. Trong môi trường MSA nơi nhiều dịch vụ chỉ xác minh, RS256 — chỉ cần phân phối khóa công khai cho bên xác minh — giảm rủi ro lộ khóa nên là lựa chọn an toàn hơn.
Thêm một điểm cần lưu ý là kích thước token. Càng đưa nhiều claim như quyền·vai trò·phòng ban vào payload thì token càng lớn, và token này đi kèm trong HTTP header của mỗi yêu cầu. Chẳng hạn nếu đưa claim quá mức khiến token lên tới vài KB, trong môi trường hàng nghìn yêu cầu mỗi giây, băng thông tích lũy và chi phí phân tích header trở nên không thể bỏ qua. Một số máy chủ web·proxy đặt giới hạn kích thước header (ví dụ 8KB), nên nếu token vượt quá thì bản thân yêu cầu có thể bị từ chối. Do đó nên thiết kế payload chỉ chứa tối thiểu các claim thực sự cần cho xác thực·phân quyền, còn thông tin chi tiết thì máy chủ tra cứu khi cần.
Bảng dưới đây tổng hợp ba thành phần, còn "lý do" của từng thành phần đã được giải thích ở các đoạn trên.
| Thành phần | Nội dung | Lưu ý thực tiễn |
|---|---|---|
| Header | Kiểu token (typ), thuật toán ký (alg) |
Cố định thuật toán cho phép ở máy chủ để chống giả mạo alg |
| Payload | Claim (đăng ký/công khai/riêng): người dùng·quyền·exp v.v. |
Không phải mã hóa → cấm thông tin nhạy cảm, bắt buộc exp |
| Signature | Ký Header+Payload bằng khóa | Quản lý khóa là tử huyệt, MSA khuyến nghị RS256 |
3. Luồng xác thực·phân quyền và chiến lược token
Sau đây là sơ đồ chi tiết quy trình từ đăng nhập đến xác minh yêu cầu, và cấp lại khi hết hạn.
sequenceDiagram
participant C as Máy khách
participant A as Máy chủ xác thực
participant R as Máy chủ tài nguyên
C->>A: 1. Đăng nhập (ID/PW)
A->>A: 2. Xác minh thông tin rồi ký JWT
A-->>C: 3. Access Token (ngắn hạn) + Refresh Token (dài hạn)
C->>R: 4. Yêu cầu + Authorization: Bearer AccessToken
R->>R: 5. Xác minh chữ ký·exp (không tra cứu kho)
R-->>C: 6. Phản hồi
Note over C,R: Khi Access Token hết hạn
C->>A: 7. Gửi Refresh Token
A-->>C: 8. Cấp lại Access Token mới
A. Cấp phát và gửi. Khi người dùng đăng nhập bằng tên đăng nhập·mật khẩu, máy chủ xác thực xác minh thông tin rồi cấp JWT đã chứa thông tin và được ký. Máy khách giữ token này và gửi kèm trong HTTP header của các yêu cầu sau dưới dạng Authorization: Bearer <token>. Máy chủ tài nguyên chỉ cần xác minh chữ ký và thời điểm hết hạn, nên chi phí khứ hồi tra cứu kho phiên biến mất. Trên thực tế, ở các API quy mô lớn, khác biệt này giảm đáng kể độ trễ phản hồi và tải của kho.
B. Đánh đổi về vị trí lưu trữ. Máy khách đặt token ở đâu là quyết định cốt lõi của thiết kế bảo mật. LocalStorage dễ thao tác nhưng truy cập được bằng JavaScript nên token có thể bị đánh cắp toàn bộ qua tấn công XSS (Cross-Site Scripting). Ngược lại, cookie HttpOnly chặn truy cập từ script nên mạnh trước XSS, nhưng do đặc tính trình duyệt tự động gửi cookie nên bị phơi nhiễm CSRF (giả mạo yêu cầu liên trang). Vì vậy trong thực tiễn thường khuyến nghị đặt token trong cookie HttpOnly+Secure+SameSite kết hợp với CSRF token. Không cách nào vạn năng nên phải chọn theo mô hình mối đe dọa.
C. Chiến lược access·refresh token. Mẫu tiêu chuẩn để giảm nhẹ điểm yếu lớn nhất của JWT — "khó cưỡng chế vô hiệu hóa" — là cấu trúc token kép. Access token có vòng đời ngắn (ví dụ 515 phút) để giảm thiểu thời gian thiệt hại nếu bị đánh cắp. Thay vào đó, để loại bỏ sự bất tiện phải đăng nhập mỗi lần, một refresh token có vòng đời dài (ví dụ vài ngàyvài tuần) được cấp riêng; khi access token hết hạn, gửi refresh token để được cấp access token mới. Refresh token gây thiệt hại lớn nếu bị đánh cắp nên máy chủ lưu·quản lý (xoay vòng Rotation, phát hiện tái sử dụng), và tại điểm này JWT nhượng bộ một phần tính phi trạng thái hoàn toàn và đưa trạng thái máy chủ trở lại. Tức là JWT trong thực tiễn không phải "phi trạng thái thuần túy" mà chọn "điểm cân bằng giữa lợi ích phi trạng thái và kiểm soát vô hiệu hóa".
D. Đánh đổi định lượng khi thiết lập vòng đời. Vòng đời token là sự cân nhắc giữa bảo mật và khả năng sử dụng. Ví dụ, nếu tăng vòng đời access token lên 60 phút, lượt gọi cấp lại giảm nên tải máy chủ và độ trễ giảm, nhưng nếu token bị đánh cắp thì có thể truy cập trái phép tối đa 60 phút. Ngược lại, nếu giảm vòng đời xuống 5 phút, cửa sổ (Window) thiệt hại khi bị đánh cắp giảm còn 1/12, nhưng lưu lượng cấp lại tới máy chủ xác thực tăng khoảng 12 lần. Vì vậy trong thực tiễn, miền có mức rủi ro càng cao thì access token càng ngắn, tính bằng phút, và bảo toàn khả năng sử dụng bằng xoay vòng refresh token. Như vậy một con số "vài phút" đồng thời quy định bảo mật·hiệu năng·khả năng sử dụng, nên thiết lập vòng đời phải dựa trên đánh giá rủi ro của miền.
4. So sánh với phương thức phiên
Cốt lõi của so sánh là "nguồn chân lý nằm ở đâu". Phiên đặt nó ở kho máy chủ, JWT đặt nó ở chính token. Từ một khác biệt này phát sinh mọi khác biệt về khả năng mở rộng·vô hiệu hóa·phơi nhiễm dữ liệu.
| Tiêu chí | Phiên (Session) | JWT |
|---|---|---|
| Lưu trạng thái | Lưu ở máy chủ (kho) | Máy khách giữ token, máy chủ phi trạng thái |
| Khả năng mở rộng | Cần chia sẻ·đồng bộ phiên (gánh nặng) | Dễ mở rộng ngang |
| Vô hiệu hóa | Có thể xóa ngay khỏi kho | Khó cưỡng chế hủy trước khi hết hạn |
| Chi phí yêu cầu | Tra cứu kho mỗi yêu cầu | Chỉ xác minh chữ ký (không tra cứu) |
| Phơi nhiễm dữ liệu | Lưu ở máy chủ (ít phơi nhiễm) | Payload có thể giải mã (cấm thông tin nhạy cảm) |
Phiên mạnh về vô hiệu hóa vì chân lý nằm ở máy chủ nên chỉ cần xóa là xong; JWT yếu về vô hiệu hóa vì chân lý đã được sao chép vào token trong tay máy khách và máy chủ không có phương tiện thu hồi. Ngược lại, JWT vượt trội về khả năng mở rộng cũng xuất phát từ cùng gốc rễ — máy chủ không phải giữ trạng thái nên có thể tự do tăng số máy chủ. Hàm ý thực tiễn rất rõ. Ngân hàng·bảng điều khiển quản trị thường xuyên cần đăng xuất cưỡng chế·vô hiệu hóa phiên tức thì thì phiên (hoặc kết hợp với phiên) có lợi hơn, còn API phi trạng thái quy mô lớn·MSA thì JWT có lợi hơn. Vì vậy đáp án không phải "cái nào tốt hơn" mà là "tối ưu hóa điều gì".
5. Chuyên sâu: Xu hướng mới nhất và các trường hợp áp dụng thực tế
A. Kết hợp với OAuth 2.0·OIDC. Ngày nay JWT ít được dùng đơn lẻ mà được tiêu chuẩn hóa làm định dạng access token của OAuth 2.0 và định dạng ID token của OpenID Connect (OIDC). ID token của OIDC thực chất là JWT, truyền đạt một cách chuẩn hóa "ai đã xác thực" qua các claim như iss·aud·exp·sub. Đăng nhập mạng xã hội của Google·Apple·Kakao v.v., cùng các IdP (Identity Provider) như Auth0·Okta·Keycloak đều dựa trên tổ hợp này. Trong dịch vụ quy mô lớn, IdP công bố danh sách khóa công khai qua endpoint JWKS (JSON Web Key Set), và mỗi máy chủ tài nguyên tải về để xác minh token. Cách này cho phép xoay vòng khóa (Key Rotation) mà không cần sửa mã phía xác minh, đơn giản hóa quản lý khóa trong môi trường gồm hàng chục~hàng trăm microservice.
B. Trường hợp thực tế trong MSA·Zero Trust. Các MSA quy mô lớn tiêu biểu như Netflix·Uber xác minh JWT lần đầu tại API gateway, và cả trong các lời gọi giữa dịch vụ nội bộ cũng lan truyền token (Token Propagation) để mỗi dịch vụ độc lập quyết định phân quyền. Điều này gắn với nguyên tắc Zero Trust — từ bỏ bảo mật dựa trên biên giới "tin tưởng mạng nội bộ" và xác minh mọi yêu cầu. Tuy nhiên, do giới hạn vô hiệu hóa của token tự chứa, mẫu đã định hình trong thực tiễn là đặt vòng đời access token ngắn tính bằng phút và kết hợp xoay vòng refresh token với phát hiện đánh cắp. Tổ hợp trong đó gateway xác minh token rồi ký lại ở dạng nhẹ hơn cho nội bộ, hoặc bảo đảm tin cậy giữa các dịch vụ ở một tầng riêng bằng TLS tương hỗ (mTLS) của service mesh, cũng được dùng rộng rãi.
C. Hướng ra đề dự kiến và chiến lược cấu trúc bài làm. Từ góc nhìn Kỹ sư chuyên nghiệp (Professional Engineer), với JWT chỉ "giải thích khái niệm" là chưa đủ; cần liên kết trình bày ① đánh đổi với phiên (khả năng mở rộng vs vô hiệu hóa), ② thiết kế bảo mật dựa trên căn cứ payload là chữ ký chứ không phải mã hóa (cấm thông tin nhạy cảm·HTTPS·exp), ③ token kép access/refresh và xoay vòng, ④ mở rộng sang OAuth2/OIDC·MSA·Zero Trust thì mới đạt điểm cao. Nêu các mối đe dọa cụ thể như tấn công nhầm lẫn alg (none·RS↔HS) hay vị trí lưu trữ (XSS vs CSRF) kèm căn cứ sẽ thể hiện được độ sâu chuyên sâu.
6. Những điểm cần cân nhắc và hàm ý
Từ góc nhìn Kỹ sư chuyên nghiệp, JWT không phải vấn đề có áp dụng một công nghệ đơn lẻ hay không, mà là vấn đề cân bằng các yếu tố xung đột — khả năng mở rộng·bảo mật·độ phức tạp vận hành — trong bối cảnh của miền. Các hàm ý dưới đây tổng hợp tiêu chí phán đoán để đạt sự cân bằng đó.
Thiết kế bảo mật là tiền đề chứ không phải lựa chọn. Payload không được mã hóa nên không đưa thông tin nhạy cảm vào, nhất định phải truyền qua HTTPS (TLS), dùng thuật toán ký mạnh và khóa đủ dài, và máy chủ phải cố định
algtrong header bằng danh sách cho phép để chặn tấn công nhầm lẫn thuật toán. Không bỏ sót xác minhexp·aud·isscũng là điều cơ bản.Bù đắp giới hạn vô hiệu hóa bằng kiến trúc. JWT đã cấp khó bị cưỡng chế hủy trước khi hết hạn, nên để ứng phó đăng xuất·đánh cắp, cần kết hợp vòng đời access token ngắn, xoay vòng·phát hiện tái sử dụng refresh token, danh sách đen dựa trên
jti(hoặc phiên bản token·ngưỡng thời điểm phát hành). Đây là quyết định từ bỏ một phần tính phi trạng thái thuần túy, nên phải lựa chọn tường minh điểm cân bằng giữa lợi ích phi trạng thái và nhu cầu kiểm soát.Thiết kế vị trí lưu trữ cùng với mô hình mối đe dọa. LocalStorage (dễ bị XSS) và cookie
HttpOnly(dễ bị CSRF) phơi nhiễm trước các mối đe dọa khác nhau, nên cần xác định vị trí lưu trữ theo mô hình mối đe dọa của dịch vụ và đồng thời phòng chống XSS (CSP·kiểm tra đầu vào)·phòng chống CSRF (SameSite·CSRF token).Theo đuổi sự tương thích với tiêu chuẩn·hệ sinh thái. Thay vì tự xây xác thực, áp dụng các tiêu chuẩn đã được kiểm chứng như OAuth 2.0·OIDC·JWKS và IdP sẽ có lợi về xoay vòng khóa·tương tác·kiểm toán. Đặc biệt trong MSA, tổ hợp RS256/ES256 — chỉ phân phối khóa công khai cho bên xác minh — với JWKS giảm rủi ro lộ khóa.
Giữ quan điểm lựa chọn công nghệ phù hợp. JWT không phải vạn năng. Với miền thường xuyên cần vô hiệu hóa tức thì·đăng xuất cưỡng chế, phiên hoặc phương thức kết hợp có thể phù hợp hơn; vì vậy so sánh với phiên theo các trục khả năng mở rộng·vô hiệu hóa·độ phức tạp vận hành để chọn phương thức phù hợp với miền chính là phán đoán của Kỹ sư chuyên nghiệp. [[msa]]
Tài liệu tham khảo
- RFC 7519, JSON Web Token (JWT) — https://datatracker.ietf.org/doc/html/rfc7519
- RFC 8725, JSON Web Token Best Current Practices — https://datatracker.ietf.org/doc/html/rfc8725
- OWASP JSON Web Token Cheat Sheet — https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html
Tóm tắt một câu: JWT là token phi trạng thái chứa thông tin xác thực và được ký, gồm Header·Payload·Signature; nhờ đặt nguồn chân lý vào chính token nên vượt trội cho xác thực MSA·API, nhưng phải bù đắp đặc điểm payload là chữ ký chứ không phải mã hóa và giới hạn cưỡng chế vô hiệu hóa bằng HTTPS·thời hạn ngắn·xoay vòng refresh token·kết hợp tiêu chuẩn (OAuth2/OIDC).