JSON Web Tokens (JWT) vs Sessions
JWT là gì ? Về bản chất, JWT là một dữ liệu chữ kí dưới dạng JSON. Bởi vì nó được "kí" nên phía nhận có thể xác minh tính xác thực của nó. Dung lượng của nó rất nhỏ vì nó là JSON. JSON Web Token (JWT) là một chuẩn mở (RFC 7519) được định nghĩa một các ngắn gọn và gọn gáng - khép kín để truyền ...
JWT là gì ?
Về bản chất, JWT là một dữ liệu chữ kí dưới dạng JSON. Bởi vì nó được "kí" nên phía nhận có thể xác minh tính xác thực của nó. Dung lượng của nó rất nhỏ vì nó là JSON.
JSON Web Token (JWT) là một chuẩn mở (RFC 7519) được định nghĩa một các ngắn gọn và gọn gáng - khép kín để truyền tải thông tin một cách an toàn giữa các bên như một JSON Objects. Thông tin này có thể được verify và đáng tin cậu bởi vì nó được kí một cách số hoá. JWTs có thể được kí sử dụng một secret ( với thuật toán HMAC) or một cặp public/private key sử dụng RSA.
Dữ liệu chữ kí ko có gì gọi là mới - cái hấp dẫn chúng ta ở đây là cách mà JWT được sử dụng để tạo nên 1 services RESTful đúng nghĩa - mà ko cần sessions. Dưới đây là cách giải thích đơn giản từ phía thế giới chúng ta cho cách mà nó hoạt động : Tưởng tượng rằng bạn vừa mới trở về nước sau 1 chuyển du lịch nước ngoài. Bạn làm thủ tục nhập cảnh và bạn nói rằng - "Hãy cho tôi qua, tôi có quốc tịch ở đây". Tất cả đều đúng cả nhưng làm cách nào bạn chứng minh với hải quan là bạn nói chính xách ? Tất nhiên bạn sẽ phải sử dụng hộ chiếu để xác thực danh tính của bạn. Hãy giả sử rằng tất cả các nhân viên cục xuất nhập cảnh có đủ thẩm quyền để khẳng định hộ chiếu của bạn là chính xác và được phát hành bởi văn phòng Hộ chiếu trong nước bạn. Hộ chiếu của bạn được xác thực và họ sẽ cho bạn qua.
OK, bây giờ hãy xem xét lại câu chuyện trên từ góc nhìn của JWT để xem ai là ai :p
- Văn phòng cấp họ chiếu - một service xác thực sẽ issue ra JWT
- Hộ chiếu - JWT của bạn được sign bởi Văn phòng hộ chiếu. Định danh của bạn sẽ có thể được đọc bởi bất kì ai nhưng chỉ có 1 số mới có thể verify được nó là thật hay giả
- Quốc tịch - yêu cầu chứa trong JWT của bạn ( hộ chiếu )
- Biên giới ( nơi làm thủ tục nhập cảnh ) - một lớp bảo mật trong app của bạn để xác minh JWT token trước khi grant access cho bạn tới các tài nguyên bên trong - trong trường hợp này là cho bạn vào nước
- Đất nước - nguồn tài nguyên bạn muốn access vào ( ví dụ các APIs)
In authentication, when the user successfully logs in using his credentials, a JSON Web Token will be returned and must be saved locally (typically in local storage, but cookies can be also used), instead of the traditional approach of creating a session in the server and returning a cookie.
Whenever the user wants to access a protected route, it should send the JWT, typically in the Authorization header using the Bearer schema. Therefore, the content of the header should look like the following:
NO SESSIONS !
Bạn không cần phải giữ các session data trên server để authen user. Các công việc cần làm sẽ chỉ như sau :
User gọi service authen, thường sẽ là gửi username và password. Authen service sẽ trả về chuối JWT - báo cho user biết họ là ai User sẽ request access tới các service đc bảo vệ bên trong bằng cách gửi lại token đó. Tầng Security sẽ check đảm bảo chữ kí trong token có chính xác hay ko để được grant access.
No sessions storage
Ko sử dụng session đòng nghĩa với việc ko cần storage lưu sessions. Nghe qua thì có vẻ ko có gì ấn tượng nhưng việc này thực sự đáng để so sanh một khi ứng dụng của bạn scale ngang. VÍ dụ , nếu bạn chạy một application trên nhiều server, thì việc sử dụng sessions sẽ là một gánh năng. Bạn hoặc sẽ phải cần một server để lưu session hoặc phải share chung disk space trên các con server đó or phải sử dụng sticky session trên load balancer. Không một việc làm nào vừa kể trên là cần thiết nếu bạn không sử dụng sessions để authen.
Không cần xử lý các session rác
Thông thường, các sessions sẽ có thời hạn hết hạn và cần phải được xử lý kiểu xoá đi các sesssions "rác". JWT hoàn toàn có thể sở hữu chính expiry date của chính nó kèm với dữ liễu user. Cho nên khi tầng Security check authen của JWT, nó có thể check expiry time của token và đơn giản là từ chối truy cập.
Truly RESTful services
Chỉ khi ko sử dụng sessions thì bạn mới có thể tạo nên 1 service thuần RESTful, bởi vì một service thuần RESTful được định nghĩa là phải stateless. Với dung lượng nhỏ, JWT có thể được gửi lên với mọi request cũng giống như session cookie. Nhưng ko giống với session cookie, nó ko cần phải trỏ đến bất kì dữ liệu nào được lưu trữ trên server, JWT đã có dữ liệu.
JWT trông như thế nào ?
Có một điều chúng ta cần phải làm rõ trước khi đi sâu hơn. JWT là gì ? trông như thế nào ? Nó hăojc là một dạng dữ liệu của JSON Web Signature (JWS) hoặc là một JSON Web Encryption.
Token trong JWT được mã hoá thành một object JSON và đc sử dụng như là một payload của cấu trúc JWS hoặc là một plaintexxt của cấu trức JWE. Vế trước cho chúng ta chỉ một chữ kí và một dữ liệu mà chữ kí đó chứa có thể đọc được bởi bất kì ai. Vế sau cho ta một cơ chế mã hoá, nơi mà chỉ có một người với chìa khoá có thể giải mã nó.
Bên trong JWT/JWS
- Header : các thông tin về thuật toán signing, type của payload (JWT) và format JSON
- Payload : các dữ liệu thực tế trong JSON format
- Signature : chữ kí
Mỗi thành phần đc nếu trên (header, payload, signature) được encode base64url, sau đó được dán lại với nahu với một "chấm" để tạo nên JWT. Dứoi đây là ví dụ :
var header = { // Thuật toán signing. "alg": "HS256", // Thuộc tính type "JWT" "typ": "JWT" }, // Object header Base64 headerB64 = btoa(JSON.stringify(header)), // The payload payload = { "name": "John Doe", "admin": true }, // Payload Object Base64 payloadB64 = btoa(JSON.stringify(payload)), // signature signature = signatureCreatingFunction(headerB64 + '.' + payloadB64), // signature Base64 signatureB64 = btoa(signature), // Đính tất cả các thành phần ở trên với dầu chấm để tạo nên JWS jwt = headerB64 + '.' + payloadB64 + '.' + signatureB64;
Kết quả của một JWS sẽ nhìn như dưới đây : Khả đẹp và gọn gàng phải ko