Tìm hiểu về JWT (JSON web token)

  1. Công nghệ thông tin

1  Tổng quan

JSON Web Token (JWT) là một chuẩn mở định nghĩa một cách nhỏ gọn và khép kín để truyền một cách an toàn thông tin giữa các bên dưới dạng đối tượng JSON. Thông tin này có thể được xác minh và đáng tin cậy vì nó có chứa chữ ký số. JWT có thể được ký bằng một thuật toán bí mật (với thuật toán HMAC) hoặc một public / private key sử dụng mã hoá RSA.

Một ví dụ về JWT Token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEzODY4OTkxMzEsImlzcyI6ImppcmE6MTU0ODk1OTUiLCJxc2giOiI4MDYzZmY0Y2ExZTQxZGY3YmM5MGM4YWI2ZDBmNjIwN2Q0OTFjZjZkYWQ3YzY2ZWE3OTdiNDYxNGI3MTkyMmU5IiwiaWF0IjoxMzg2ODk4OTUxfQ.uKqU9dTB6gKwG6jQCuXYAiMNdfNRw98Hw_IWuA5MaMo

2  Chi tiết JWT

2.1      Cấu trúc

<base64-encoded header>.<base64-encoded payload>.<base64-encoded signature> 
JWT là sự kết hợp (bởi dấu .) với 3 thành phần:

-       Đầu tiên là Object Header dưới định dạng JSON.

-       Tiếp theo là payload object dưới định dạng JSON.

-       Cuối cùng là một Signature cho URI.

Cả 3 thành phần đều được mã hóa base64.

2.2      Chi tiết cấu trúc JWT

2.2.1          Header

Header bao gồm hai phần chính:

-      Loại token (mặc định là JWT - Thông tin này cho biết đây là một Token JWT).

-      Thuật toán đã dùng để mã hóa (HMAC SHA256 - HS256 hoặc RSA).


{  "alg": "HS256",  "typ": "JWT" } 
2.2.2          Payload

Payload chứa các claims. Claims là một các biểu thức về một thực thể (chẳng hạn user) và một số metadata phụ trợ.

Có 3 loại claims thường gặp trong Payload:

-      Reserved.

-      Public.

-      Private claims.

Reserved claims: Đây là một số metadata được định nghĩa trước, trong đó một số metadata là bắt buộc, số còn lại nên tuân theo để JWT hợp lệ và đầy đủ thông tin:

-       iss (mã phát hành)

-       iat (phát hành vào lúc)

-      exp (thời gian hết hạn)

-      sub (tên đối tượng gửi đi)

-      aud (Người nhận)

-      jti (Unique Identifier cho JWT, có thể được sử dụng để ngăn JWT được phát lại.) ...

Ví dụ:

{

   "iss": "jira:1314039",

   "iat": 1300819370,

   "exp": 1300819380,

   "qsh": "8063ff4ca1e41df7bc90c8ab6d0f6207d491cf6dad7c66ea797b4614b71922e9",

   "sub": "batman",

   "context": {

       "user": {

           "userKey": "batman",

           "username": "bwayne",

           "displayName": "Bruce Wayne"

       }

   }

}


{  "iss": "scotch.io",  "exp": 1300819380,  "name": "Chris Sevilleja",  "admin": true } 

Public Claims: Claims: được cộng đồng công nhận và sử dụng rộng rãi.

Private Claims: Claims tự định nghĩa (không được trùng với Reserved Claims và Public Claims), được tạo ra để chia sẻ thông tin giữa 2 bên đã thỏa thuận và thống nhất trước đó.


2.2.3          Signature

Chữ ký Signature trong JWT là một chuỗi được mã hóa bởi header, payload cùng với một chuỗi bí mật theo nguyên tắc sau:

HMACSHA256(  base64UrlEncode(header) + "." +  base64UrlEncode(payload),  secret) 
Do bản thân Signature đã bao gồm cả header và payload nên Signature có thể dùng để kiểm tra tính toàn vẹn của dữ liệu khi truyền tải.


3  Ứng dụng

·     Authentication: Tình huống thường gặp nhất, khi user logged in, mỗi request tiếp đó đều kèm theo chuỗi token JWT, cho phép người dùng có thể truy cập đường dẫn, dịch vụ và tài nguyên được phép ứng với token đó.

·     Single Sign On : cũng là một chức năng có sử dụng JWT một cách rộng rãi, bởi vì chuỗi JWT có kích thước đủ nhỏ để đính kèm trong request và sử dụng ở nhiều hệ thống thuộc các domain khác nhau.

·     Information Exchange: JSON Web Token cũng là một cách hữu hiệu và bảo mật để trao đổi thông tin giữa nhiều ứng dụng, bởi vì JWT phải được ký (bằng cặp public / private key), bạn có thể chắc rằng người gửi chính là người mà họ nói rằng họ là (nói tóm tắt hơn là không hoặc khó để mạo danh bằng JWT), ngoài ra, chữ ký cũng được tính toán dựa trên nội dung của header và nội dung payload, nhờ đó, bạn có thể xác thực được nội dung là nguyên bản, chưa được chỉnh sửa hoặc can thiệp. Tuy nhiên, một lưu ý hết sức quan trọng là do cấu trúc của JWT đơn giản nên JWT có thể dễ dàng bị decode, do vậy, bạn không nên dùng JWT để transfer các thông tin nhạy cảm.


3.1      Ví dụ

Ở đây, mình ví dụ cụ thể ứng dụng của JWT trong bài toán Authenticate (xác thực) - Trong việc xác thực, khi user đăng nhập thành công (Browser sẽ post username và mật khẩu về Server), Server sẽ trả về một chuỗi JWT về Browser, và Token JWT này cần được lưu lại trong Browser của người dùng (thường là LocalStorage hoặc Cookies), thay vì cách truyền thống là tạo một session trên Server và trả về Cookie.

Bất cứ khi nào mà User muốn truy cập vào Route được bảo vệ (mà chỉ có User đã đăng nhập mới được phép), Browser sẽ gửi token JWT này trong Header Authorization, Bearer schema của request gửi đi.

Authorization: Bearer <token> 
Đây là cách mà stateless (phi trạng thái) authentication làm việc, trạng thái của user không được lưu trong bộ nhớ của Server mà được đóng gói hẳn vào trong JWT. Server sẽ kiểm tra Token JWT này có hợp lệ hay không (Bởi vì JWT có tính chất khép kín, mọi thông tin cần thiết để kiểm tra JWT đều đã được chứa trong Token JWT).

Do tính chất stateless nên chúng ta không còn phải lo lắng về domains nào được sử dụng cho API của bạn, như không còn gặp rắc rối với CORS (Cross-Origin Resource Sharing) vì nó không sử dụng cookies.

Sơ đồ dưới đây cho thấy quá trình này

Picture1


Từ khóa: 

jwt

,

vtcc_intern_7

,

công nghệ thông tin