Giải mã JWT
Giải mã và kiểm tra JSON Web Token
Token JWT
JWT (JSON Web Token) là gì?
JSON Web Token (JWT) là định dạng token nhỏ gọn, an toàn cho URL, được định nghĩa trong RFC 7519. Nó mã hóa một tập hợp các claim dưới dạng đối tượng JSON, sau đó ký — và tùy chọn mã hóa — để người nhận có thể xác minh dữ liệu không bị giả mạo. JWT là tiêu chuẩn thực tế cho xác thực không trạng thái trong REST API, hệ thống đăng nhập một lần và phân quyền microservice.
Cấu trúc JWT: Header · Payload · Signature
Mỗi JWT gồm ba đoạn mã hóa base64url ngăn cách bởi dấu chấm. Header và Payload là JSON thuần — ai cũng có thể đọc — trong khi Signature là giá trị mật mã chỉ có thể xác minh bằng khóa đúng.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzE3MjAwMDAwLCJleHAiOjE3MTcyMDM2MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "user123",
"name": "Alice",
"role": "admin",
"iat": 1717200000,
"exp": 1717203600
}Tại sao dùng JWT Decoder?
JWT thô trông như văn bản ngẫu nhiên. Công cụ này hiển thị ngay Header và Payload dưới dạng JSON có định dạng để bạn kiểm tra các claim, xem thời hạn hết hạn và kiểm tra lựa chọn thuật toán mà không cần viết một dòng code nào.
Tham chiếu các Claim JWT chuẩn
RFC 7519 định nghĩa bảy tên claim đã đăng ký. Chúng không bắt buộc, nhưng việc sử dụng được khuyến nghị mạnh mẽ để đảm bảo khả năng tương tác. Bạn có thể thêm bất kỳ claim tùy chỉnh nào vào Payload.
| Claim | Mô tả | Kiểu |
|---|---|---|
| iss | Người phát hành — Xác định ai đã phát hành token — ví dụ URL máy chủ xác thực hoặc tên ứng dụng của bạn. | string |
| sub | Chủ thể — Xác định đối tượng mà JWT đề cập — thường là ID người dùng hoặc tài khoản dịch vụ. | string |
| aud | Đối tượng — Xác định người nhận dự định. Bên nhận phải xác minh rằng điều này khớp với định danh của họ. | string | string[] |
| exp | Thời gian hết hạn — Dấu thời gian Unix sau đó token không được chấp nhận. Luôn đặt giá trị này để hạn chế thiệt hại từ token bị đánh cắp. | number |
| nbf | Không trước — Dấu thời gian Unix trước đó token không được chấp nhận. Hữu ích để lên lịch các token có ngày trong tương lai. | number |
| iat | Được phát hành lúc — Dấu thời gian Unix khi token được phát hành. Dùng để tính tuổi của token. | number |
| jti | JWT ID — Định danh duy nhất cho token. Cho phép thu hồi bằng cách lưu trữ và kiểm tra các giá trị JTI đã dùng ở phía máy chủ. | string |
Thuật toán ký JWT
Claim header alg khai báo thuật toán nào đã ký token. Lựa chọn ảnh hưởng đến bảo mật, hiệu suất và liệu các dịch vụ bên thứ ba có thể xác minh token mà không cần khóa riêng tư hay không.
| Thuật toán | Họ thuật toán | Loại khóa | Ghi chú |
|---|---|---|---|
| HS256 | HMAC | Symmetric | Phổ biến nhất. Bí mật chung — bất kỳ ai có bí mật đều có thể ký và xác minh. |
| HS384 | HMAC | Symmetric | Biến thể HMAC mạnh hơn; chi phí hiệu suất vừa phải. |
| HS512 | HMAC | Symmetric | Biến thể HMAC mạnh nhất. |
| RS256 | RSA | Asymmetric | Thuật toán bất đối xứng được dùng rộng rãi nhất (Google, Auth0, Okta). Khóa công khai xác minh mà không cần khóa riêng. |
| RS384 | RSA | Asymmetric | Biến thể RS bảo mật cao hơn. |
| RS512 | RSA | Asymmetric | Biến thể RS mạnh nhất. |
| ES256 | ECDSA | Asymmetric | Đường cong elliptic — chữ ký ngắn hơn RSA, phổ biến trên thiết bị di động và IoT. |
| PS256 | RSA-PSS | Asymmetric | RSA-PSS: hiện đại và an toàn hơn RS256 dựa trên PKCS1v1.5. |
| none | — | — | Không có chữ ký — cực kỳ nguy hiểm. Không bao giờ chấp nhận token với alg: none trong môi trường sản xuất. |
Cân nhắc về bảo mật
Giải mã JWT luôn an toàn. Tin tưởng JWT mà không xác minh chữ ký đúng cách thì không an toàn. Hãy ghi nhớ những quy tắc này mỗi khi bạn dùng token trong ứng dụng của mình.
- –Giải mã và kiểm tra JWT trong công cụ dành cho nhà phát triển hoặc công cụ này
- –Dùng exp, iat và nbf để hiểu thời hạn sống của token
- –Ghi nhật ký các claim Payload để gỡ lỗi (bỏ qua thông tin cá nhân nhạy cảm)
- –Đọc header alg để hiểu cách token được ký
- –Tin tưởng các claim trong Payload mà không xác minh chữ ký phía máy chủ
- –Chấp nhận token với alg: none — điều này có nghĩa là không có chữ ký nào cả
- –Lưu trữ token truy cập trong localStorage trên các ứng dụng có bảo mật cao (ưu tiên cookie httpOnly)
- –Đặt exp quá xa trong tương lai cho các token mang quyền nhạy cảm
Các trường hợp sử dụng phổ biến
Giải mã JWT trong code
Header và Payload được mã hóa base64url — chỉ cần đảo ngược mã hóa. Base64url thay + bằng - và / bằng _, và bỏ qua ký tự đệm =. Chỉ Signature mới cần khóa bí mật.
function decodeJWT(token) {
const [, payload] = token.split('.')
const json = atob(payload.replace(/-/g, '+').replace(/_/g, '/'))
return JSON.parse(json)
}const [, payload] = token.split('.')
const decoded = JSON.parse(
Buffer.from(payload, 'base64url').toString()
)import base64, json
def decode_jwt(token):
payload = token.split('.')[1]
padding = '=' * (-len(payload) % 4)
return json.loads(base64.urlsafe_b64decode(payload + padding))TOKEN="eyJhbGc..." echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq .