Menu

Giải mã JWT

Phân tích và xác minh JSON Web Token theo từng phần payload.

Tác giả Nethanel Bar, Co-founder & CEO

Cập nhật lần cuối

Sẵn sàng học code thật sự?

Coddy dạy bạn bằng cách viết code thật ngay trên trình duyệt: bài học tương tác, phản hồi tức thì và AI hỗ trợ khi bạn bị kẹt.

JWT decoder là gì?

JWT decoder tách một JSON Web Token thành ba phần, gồm header, payload và chữ ký (signature), rồi giải mã Base64URL hai phần đầu để bạn đọc chúng dưới dạng JSON. Lập trình viên dùng công cụ này liên tục khi gỡ lỗi luồng đăng nhập, phân quyền, claim của phiên làm việc và các vấn đề token hết hạn.

Giải mã một JWT *không* có nghĩa là tin tưởng nó. Header và payload được thiết kế để ai cũng đọc được: chúng chỉ được mã hóa Base64URL chứ không được mã hóa bảo mật. Xác minh mới là bước kiểm tra xem token có được ký bởi đúng bên mong đợi và chưa bị chỉnh sửa hay không.

Một JWT có dạng header.payload.signature. Mỗi phần được mã hóa Base64URL và phân tách bằng dấu chấm. Header cho biết thuật toán ký được dùng, payload chứa các claim (người dùng là ai, khi nào token hết hạn, họ được phép làm gì), còn chữ ký giúp máy chủ chứng minh token chưa bị sửa đổi.

Bạn sẽ học được gì khi giải mã JWT

  • Một JWT có ba phần được mã hóa Base64URL, phân tách bằng dấu chấm: header.payload.signature.
  • Các claim phổ biến như sub, role, iat, nbf và exp mô tả danh tính, quyền hạn, thời điểm phát hành và thời điểm hết hạn.
  • Ai cũng có thể sửa payload đã giải mã: chỉ chữ ký mới giúp máy chủ phát hiện token bị giả mạo.
  • Các thuật toán khác nhau: HS256 dùng một khóa bí mật chung; RS256 và ES256 dùng cặp khóa công khai và khóa riêng. Trường alg trong header cho bạn biết thuật toán nào được dùng.

Cách giải mã JWT từng bước

  1. Dán toàn bộ token

    Dán JWT vào ô nhập. Token có dạng xxxx.yyyy.zzzz: ba phần mã hóa Base64URL nối với nhau bằng dấu chấm.

  2. Đọc header

    Header cho biết thuật toán ký (alg) và loại token. Hãy cẩn thận với "alg": "none": nghĩa là token không được ký và không thể tin tưởng.

  3. Đọc các claim trong payload

    Payload là đoạn JSON chứa tất cả claim. Tìm sub (id người dùng), exp (thời điểm hết hạn), iat (thời điểm phát hành) và mọi claim tùy chỉnh mà ứng dụng của bạn thêm vào như role hoặc tenant.

  4. Kiểm tra thời hạn

    Đổi Unix timestamp trong exp sang ngày tháng: nếu thời điểm đó đã qua, token đã hết hạn và mọi API tuân thủ đúng chuẩn đều sẽ từ chối nó.

  5. Xác minh chữ ký (tùy chọn)

    Nếu có khóa bí mật hoặc khóa công khai, dán vào phần xác minh để kiểm tra chữ ký có hợp lệ không. Nội dung token chỉ đáng tin khi chữ ký hợp lệ.

Các claim JWT chuẩn

Đây là các claim đã đăng ký do đặc tả JWT định nghĩa (RFC 7519). Ứng dụng nào cũng có thể thêm claim tùy chỉnh của riêng mình bên cạnh các claim này.

ClaimTênÝ nghĩa
issBên phát hành (Issuer)Ai đã tạo và ký token
subChủ thể (Subject)Token nói về ai, thường là id người dùng
audĐối tượng nhận (Audience)Token được cấp cho ai
expHết hạn (Expiration)Unix timestamp mà sau thời điểm đó token không còn hợp lệ
nbfKhông trước (Not Before)Token không được chấp nhận trước thời điểm này
iatPhát hành lúc (Issued At)Thời điểm token được tạo
jtiJWT IDMã định danh duy nhất, hữu ích để thu hồi token
algAlgorithm (header)Thuật toán ký: HS256, RS256, ES256, …

Ví dụ JWT để thử

Xem một JWT điển hình

Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsInJvbGUiOiJzdHVkZW50IiwiZXhwIjoxNzEwMDAwMDAwfQ.Q3hH8yzqI2OsHJ1Lyj8jJfJPa5ZpIVlh1FhJpJbqMcs

Header
{  "alg": "HS256",  "typ": "JWT"}
Payload
{  "sub": "user_123",  "role": "student",  "exp": 1710000000}

Header cho biết HS256 (thuật toán dùng khóa bí mật chung). Payload xác định người dùng, vai trò của họ và thời điểm token hết hạn. Chữ ký là phần thứ ba. (Đây là token mẫu để minh họa: chữ ký sẽ không khớp với bất kỳ khóa bí mật thật nào.)

Kiểm tra token đã hết hạn chưa

Claim trong payload
{  "exp": 1710000000}

exp là Unix timestamp tính bằng giây. Đổi nó sang ngày tháng: nếu thời điểm đó đã qua, token đã hết hạn và một backend đúng chuẩn sẽ từ chối nó.

Nhận diện thuật toán "none" nguy hiểm

Header
{  "alg": "none",  "typ": "JWT"}

Nếu máy chủ chấp nhận "alg": "none", kẻ tấn công có thể giả mạo bất kỳ payload nào mà không cần chữ ký. Luôn từ chối header này trên môi trường production.

Lỗi thường gặp với JWT

  • Đưa mật khẩu, khóa bí mật hoặc dữ liệu cá nhân nhạy cảm vào payload. JWT đọc được, không được mã hóa bảo mật.
  • Giải mã một token rồi cho rằng nó hợp lệ mà không kiểm tra chữ ký.
  • Nhầm việc đọc được nhờ Base64URL với mã hóa bảo mật: payload JWT được thiết kế để dễ đọc.
  • Lưu JWT trong localStorage mà không cân nhắc rủi ro XSS, rồi lại đặt thời hạn rất dài.
  • Không kiểm tra claim aud (audience): token cấp cho một dịch vụ có thể bị dùng lại ở dịch vụ khác nếu bên nhận không kiểm tra.

Câu hỏi thường gặp về JWT

JWT là gì?

JWT là viết tắt của JSON Web Token. Đây là định dạng token gọn nhẹ, có chữ ký, an toàn với URL, dùng để truyền claim giữa hai bên, thường là giữa máy chủ và trình duyệt để đại diện cho người dùng đã đăng nhập.

Làm sao để giải mã JWT?

Dán token vào một JWT decoder, hoặc tách token theo dấu chấm và giải mã Base64URL từng phần trong hai phần đầu. Header và payload trả về dưới dạng JSON; phần thứ ba là chữ ký.

Làm sao kiểm tra JWT đã hết hạn chưa?
Xem claim exp trong payload. Đây là Unix timestamp tính bằng giây. Nếu thời điểm hiện tại đã qua exp, token đã hết hạn.
Ai cũng giải mã được JWT phải không?

Đúng vậy. Header và payload chỉ được mã hóa Base64URL, không được mã hóa bảo mật. Chữ ký chỉ chứng minh token chưa bị chỉnh sửa, nó không che giấu nội dung.

Xác minh JWT nghĩa là gì?

Xác minh là tính lại chữ ký bằng khóa bí mật hoặc khóa công khai mong đợi rồi so sánh với chữ ký trên token. Nếu khớp, payload đáng tin và chưa bị sửa đổi.

Có nên lưu mật khẩu trong JWT không?

Không. Ai có token đều đọc được payload. Chỉ lưu các mã định danh và claim không nhạy cảm, và dựa vào thời hạn ngắn cùng refresh token để đảm bảo an toàn.

Tìm hiểu thêm

Công cụ lập trình khác

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu