Với thời đại mobile app, web app trở nên phổ biến, việc sử dụng authenticate (xác thực) bằng JWT (JSON Web Token) đã trở nên phổ biến và được triển khai rất rộng rãi.
Dù bạn là lập trình viên backend hay frontend, việc hiểu biết về JWT và cách thức hoạt động cũng như chức năng cốt lõi là điều cần thiết để có thể sử dụng và triển khai đúng cách và tận dụng tối đa khả năng của nó.
Trong bài viết này, chúng ta sẽ cùng tìm hiểu chi tiết đến JWT, các khái niệm, thành phần trong đó và một số ứng dụng thực tiễn của JWT.
1. JWT (JSON Web Token) là gì
JWT (JSON Web Token) là một tiêu chuẩn mã nguồn mở (RFC 7519) dùng để truyền tải thông tin an toàn, gọn nhẹ và khép kín giữa các bên tham gia dưới format JSON.
Thông tin được chia sẻ trong JWT được xác thực và tin cậy thông qua chữ ký số (Digital signature). Các bên sẽ sử dụng mật mã khoá đối xứng (cùng với HMAC) hoặc dùng mật mã khoá công khai (cùng public và private key) để thực hiện ký số (signed).
JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties.
Nguồn: https://datatracker.ietf.org/doc/html/rfc7519
2. Cấu tạo của JWT
JWT gồm 3 phần chính, và phần tách nhau bằng một dấu chấm (.
):
- Header
- Payload
- Signature
Vì vậy, JWT sẽ có dạng như sau :
Chúng ta cùng đi chi tiết để từng thành phần của JWT
2.1 Header
Header thông thường sẽ bao gồm 2 thành phần, gồm : Kiểu token, mà với trường hợp này luôn luôn là JWT, và thuật toán mã hoá được sử dụng, ví dụ như HMAC hoặc RSA.
Do đó, Header của JWT sẽ có dạng như sau.
{
"alg": "HS256",
"typ": "JWT"
}
Sau đó, đoạn này sẽ được encoding (base64Encode) và trở thành chuỗi đầu tiên trong 3 chuỗi JWT.
2.2 Payload
Payload trong JWT chứa các claims.
Trong lĩnh vực an toàn thông tin, claims đề cập đến sự tuyên bố quyền truy cập hoặc quyền sử dụng tài nguyên.
Claims là tập hợp các thông tin đại diện cho một thực thể (object) (ví dụ : user_id) và một số thông tin đi kèm. Claims sẽ có dạng Key - Value. Do đó, chúng ta có thể hiểu rằng, claims ám chỉ việc yêu cầu truy xuất tài nguyên cho object tương ứng.
Có 3 kiểu claims, bao gồm registered, public, and private claims.
2.2.1 Registered Claims
Registered Claims là các thành phần được xác định trước của claims. Thành phần này mặc dù không bắt buộc, nhưng là thành phần nên có để cung cấp một số chức năng và thông tin hữu ích.
Một số registered claims bao gồm :
iss
(issuer): Tổ chức, đơn vị cung cấp, phát hành JWT.sub
(subject): Chủ thể của JWT, xác định rằng đây là người sở hữu hoặc có quyền truy cập các resource (tài nguyên).aud
(audience): Được hiểu là người nhận thông tin, và có thể xác thực tính hợp lệ của JWT.exp
(expiration time): Thời hạn của JWT, vượt quá thời gian này, JWT được coi là không hợp lệ
2.2.2 Public Claims
Public claims là các thành phần được xác định bởi người sử dụng JWT, được sử dụng rộng rãi trong JWT. Mặc dù việc sử dụng public claims không phải là bắt buộc, tuy nhiên để tránh xảy ra xung đột, public claims name được xác định theo danh sách dưới đây:
Claim Name | Claim Description |
---|---|
iss | Issuer |
sub | Subject |
aud | Audience |
exp | Expiration Time |
nbf | Not Before |
iat | Issued At |
jti | JWT ID |
name | Full name |
given_name | Given name(s) or first name(s) |
family_name | Surname(s) or last name(s) |
middle_name | Middle name(s) |
nickname | Casual name |
preferred_username | Shorthand name by which the End-User wishes to be referred to |
profile | Profile page URL |
picture | Profile picture URL |
Danh sách các public claims
Một số public claims điển hình :
name, given_name, family_name, middle_name
: Thông tin tên nói chung của useremail
: Thông tin email của user.locale
: Địa chỉ của user.profile, picture
: Thông tin của trang web gửi đến.
2.2.3 Private Claims
Các bên sử dụng JWT có thể sẽ cần sử dụng đến claims không phải là Registered Claims, cũng không được định nghĩa trước như Public Claims. Đây là phần thông tin mà các bên tự thoả thuận với nhau, không có tài liệu hay tiêu chuẩn nào dành cho private claims.
Lưu ý: Tên claims chỉ nên dài ba ký tự vì JWT hướng tới sự nhỏ gọn.
2.3 Signature
Signature là phần cuối cùng của JWT, có chức năng xác thực danh tính người gửi. Để tạo ra một signature chính xác, ta cần encode phần header, phần payload, chọn cryptography (mật mã khoá) thích hợp đã được xác định ở header kèm secret key và thực hiện sign.
Ví dụ, nếu chúng ta lựa chọn hàm HMACSHA256, function thực hiện sign sẽ có dạng như sau:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
Cả bên gửi và bên nhận JWT đều sẽ xử dụng hàm này để xác định phần signature, nếu thông tin này của cả 2 bên khác nhau, JWT này được coi là không hợp lệ.
Lưu ý: Chỉ có người có secret key mới có thể sign được một signature phù hợp. Do đó, danh tính của bên gửi được đảm bảo nhờ có signature.
3. Lý do sử dụng JWT
- Authentication (Xác thực): JWT được sử dụng để xác thực người dùng trước khi họ truy cập đến tài nguyên trên server.
- Authorization (Uỷ quyền): Khi người dùng đăng nhập thành công, application có thể truy cập vào các tài nguyên thay mặt người dùng đó. Các ứng dụng đăng nhập một lần (Single Sign-On SSO) sử dụng JWT thường xuyên vì tính nhỏ gọn và dễ dàng triển khai trên nhiều domain.
- Trao đổi thông tin an toàn: JWT được coi là một cách trao đổi thông tin an toàn vì thông tin đã được signed trước khi gửi đi.
4. Ưu điểm của JWT
- Gọn nhẹ: JWT nhỏ gọn, chi phí truyền tải thấp giúp tăng hiệu suốt của các ứng dụng.
- Bảo mật: JWT sử dụng các mật mã khoá để tiến hành xác thực người danh tính người dùng. Ngoài ra, cấu trúc của JWT cho phép chống giả mạo nên thông tin được đảm bảo an toan trong quá trình trao đổi.
- Phổ thông: JWT được sử dụng dựa trên JSON, là một dạng dữ liệu phổ biến, có thể sử dụng ở hầu hết các ngôn ngữ lập trình. Ngoài ra, triển khai JWT tương đối dễ dàng và tích hợp được với nhiều thiết bị, vì JWT đã tương đối phổ biến.
5. Khuyết điểm của JWT
- Kích thước: Mặc dù trong tài liệu không ghi cụ thể giới hạn, nhưng do được truyền trên HTTP Header, vì thế, JWT có giới hạn tương đương với HTTP Header (khoảng 8KB).
- Rủi ro bảo mật: Khi sử dụng JWT không đúng cách, ví dụ như không kiểm tra tính hợp lệ của signature, không kiểm tra expire time, kẻ tấn công có thể lợi dụng sơ hở để truy cập vào các thông tin trái phép.
Ngoài ra, việc để thời gian hết hạn của JWT quá dài cũng có thể tạo ra kẽ hở tương tự.
6. Một số ứng dụng JWT
- Single Sign-On (SSO): JWT có thể được sử dụng để cung cấp single sign-on cho người dùng. Điều này cho phép họ đăng nhập vào nhiều ứng dụng chỉ với một tài khoản duy nhất.
- API Authorization: JWT thường được sử dụng để phân quyền cho người dùng đến những tài nguyên cụ thể, từ những claims chứa trong JWT đó.
- User Authentication: JWT cung cấp khả năng xác thực người dùng và cấp quyền cho họ truy cập vào các tài nguyên mong muốn trong hệ thống.
- Microservices Communication: JWT còn có thể sử dụng cho việc giao tiếp giữa các service nhỏ trong hệ thống microservices.
7. Kết luận
WT thường được sử dụng trong các hệ thống xác thực và ủy quyền, đặc biệt là trong các ứng dụng web và dịch vụ API, nhờ vào tính gọn nhẹ và khả năng tích hợp dễ dàng với các hệ thống khác nhau. Tuy nhiên, việc triển khai JWT cũng cần được thực hiện cẩn thận để tránh các lỗ hổng bảo mật, đảm bảo rằng mã hóa và ký số được thực hiện đúng cách, các token được quản lý hiệu quả.
Các bài viết liên quan tại blog 200Lab:
Bài viết liên quan
Giới thiệu Kiến trúc Backend for Frontend (BFF)
Nov 16, 2024 • 10 min read
Flask là gì? Hướng dẫn tạo Ứng dụng Web với Flask
Nov 15, 2024 • 7 min read
Webhook là gì? So sánh Webhook và API
Nov 15, 2024 • 8 min read
Spring Boot là gì? Hướng dẫn Khởi tạo Project Spring Boot với Docker
Nov 14, 2024 • 6 min read
Two-Factor Authentication (2FA) là gì? Vì sao chỉ Mật khẩu thôi là chưa đủ?
Nov 13, 2024 • 7 min read
Test-Driven Development (TDD) là gì? Hướng dẫn thực hành TDD
Nov 13, 2024 • 6 min read