Site icon LCDUNG

JWT là gì?

Dạo gần đây cái blog móc meo này không cập nhật gì vì bận với dự án cày toàn công nghệ của Yahoo như Athenz, CorpIT,… mà từ mấy này mình học được nhiều thứ trong đó có phương pháp Authentication dùng JWT (JSON Web Token). Cái này thấy đã ra đời lâu rồi người ta áp dụng nhiều rồi mà giờ mình mới nghiên cứu tới! viết bài này để tự share cho mình, JWT là gì và những lợi ích gì mà JWT có thể đem lại cho Web Service ngoài việc chứng thực.

JWT là gì?

JWT (JSON Web Token) là 1 tiêu chuẩn mở (RFC 7519) định nghĩa cách thức truyền tin an toàn giữa các bên bởi JSON. Thông tin này có thể được xác thực và đánh dấu tin cậy nhờ vào “chữ ký” của nó. Phần chữ ký của JWT sẽ được mã hóa lại bằng HMAC hoặc RSA.

Những đặc điểm nổi bật của JWT:

  1. Kích thước nhỏ: JWT có thể được truyền thông qua query parameter trên URL, HTTP Header, Cookie, Post…. Kích thước nhỏ hơn ứng với công việc truyền tải sẽ nhanh hơn. Dưới đây là cách thức truyền token vào trong HTTP Header sử dụng Bearer Schema.
  2. Khép kín: toàn bộ những thông tin bảo mật sẽ được đóng kính trong phần Payload của JWT và được mã hóa bởi secret key.

Tại sao dùng JWT?

Dưới đây là 1 vài kịch bản nên dùng JWT:

Cấu trúc của JWT:

JWT bao gồm 3 phần, được ngăn cách nhau bởi dấu chấm (.):

  1. Header
  2. Payload
  3. Signature

Tổng quát thì nó có dạng như sau:

See the gist on github.

Header:

Phần Header dùng để khai báo kiểu chữ ký và thuật toán mã hóa sẽ dùng cho cái token của chúng ta.

See the gist on github.

Đoạn Header này khai báo rằng đối tượng được mã hóa là 1 JWT (để phân biệt với JWS hay JWE), và chữ ký của nó sử dụng thuật toán mã hóa HMAC SHA-256.

Đoạn Header này sẽ được mã hóa base64url, và ta thu được phần đầu tiên của JWT:

See the gist on github.

Chú ý rằng mình viết ở phía trên là base64url chứ không phải là base64. Về cơ bản 2 cái này là tương tự nhau nhưng giữa chúng vẫn có những sự khác biệt:

​Các bạn có thể so sánh sự khác biệt của chúng ở trang web encode online này:
http://kjur.github.io/jsjws/tool_b64uenc.html

Chúng ta có thể tự triển khai 1 hàm encode base64url do chính mình tạo ra. Dưới đây là code mô phỏng bằng Javascript:

See the gist on github.

Ở đoạn code trên mình đã sử dụng thư viện CryptoJS để có thể mã hóa base64 rồi sau đó loại bỏ các ký tự = và thay thế các ký tự + / đi.

Để có thể sử dụng được hàm trên, đầu vào của bạn cần là 1 mảng byte ở định dạng UTF-8. Ta có thể chuyển đổi từ xâu ký tự sang mảng byte bằng 1 hàm khác cũng được cung cấp bởi CryptoJS:

See the gist on github.

Cuối cùng ta đã thu được phần đầu tiên của JWT:

See the gist on github.

Payload (Claims):

Phần thứ 2 của token đó là Payload, nơi chứa các nội dung của thông tin (claim). Thông tin truyền đi có thể là mô tả của 1 thực thể (ví dụ như người dùng) hoặc cũng có thể là các thông tin bổ sung thêm cho phần Header. Nhìn chung, chúng được chia làm 3 loại: reserved, public và private.

  1. Reserved: là những thông tin đã được quy định ở trong IANA JSON Web Token Claims registry. Chúng bao gồm: Chú ý rằng các khóa của claim đều chỉ dài 3 ký tự vì mục đích giảm kích thước của Token
    • iss (issuer): tổ chức phát hành token
    • sub (subject): chủ đề của token
    • aud (audience): đối tượng sử dụng token
    • exp (expired time): thời điểm token sẽ hết hạn
    • nbf (not before time): token sẽ chưa hợp lệ trước thời điểm này
    • iat (issued at): thời điểm token được phát hành, tính theo UNIX time
    • jti: JWT ID
  2. Public: Khóa nên được quy định ở trong IANA JSON Web Token Registry hoặc là 1 URI có chứa không gian tên không bị trùng lặp.
  3. Private: Phần thông tin bảo mật dùng để gửi qua các services.

 

Ví dụ Payload:

See the gist on github.

Mã hóa base64url ta thu được phần thứ 2 của token:

See the gist on github.

Signature:

Phần chữ ký được tạo bằng cách kết hợp 2 phần Header + Payload, rồi mã hóa nó lại bằng 1 giải thuật encode nào đó, càng phức tạp thì càng tốt, ví dụ như HMAC SHA-256

See the gist on github.

Rồi ta sẽ thu được phần cuối của token:

See the gist on github.

Putting All Together:

Gom lại từ ví dụ trên sẽ có dạng là:

See the gist on github.

Và đây là đoạn code Javascript triển khai toàn bộ công việc trên:

See the gist on github.

Source code để hiểu tạo JWT thôi vì hiện nay đã có rất nhiều library hỗ trợ việc trên rất tốt. Bạn có thể tham khảo: https://jwt.io/

Nếu đang lập trình Node.js thì nên dùng: https://github.com/auth0/node-jsonwebtoken

Sẽ viết bài hướng dẫn dùng Nodejs để build JWT sau…

Exit mobile version