I. Kiến thức Cần chuẩn bị
1. Kiểu Dữ liệu JSON
JSON (JavaScript Object Notation) là định dạng dữ liệu nhẹ, dễ đọc và dễ viết, được sử dụng phổ biến trong các ứng dụng web và di động. Nó cho phép truyền tải và lưu trữ dữ liệu theo dạng key-value trong dấu ngoặc nhọn { }
với các cặp được phân cách bằng dấu phẩy. Ví dụ cơ bản về JSON như sau:
{
"name": "John",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345"
},
"phoneNumbers": [
{
"type": "home",
"number": "555-555-1234"
},
{
"type": "work",
"number": "555-555-5678"
}
]
}
2. JSON Web Token (JWT) là gì?
Trong các ứng dụng web hiện đại, phương pháp xác thực truyền thống như cookie và session thường gặp một số vấn đề lớn, nhất là khi số lượng người dùng tăng lên nhanh chóng.
- Việc lưu trữ thông tin xác thực (session) trên máy chủ gây tốn kém tài nguyên khi có nhiều người dùng.
- Người dùng chỉ có thể truy cập tài nguyên trên máy chủ nơi họ đã xác thực, gây giới hạn khả năng mở rộng cho ứng dụng.
- Thông tin lưu trữ trong session thường bị giới hạn về kích thước.
- Nếu session bị đánh cắp, có thể dẫn đến các cuộc tấn công CSRF hoặc XSRF.
Để giải quyết những vấn đề này, JSON Web Token (JWT) được phát triển như một giải pháp xác thực an toàn, giúp trao đổi thông tin nhanh chóng giữa các ứng dụng. JWT là một tiêu chuẩn mã hóa thông tin dựa trên định dạng JSON, được quy định trong RFC 7519.
3. Cấu trúc của JWT
JWT bao gồm ba phần chính: header, payload, và signature, được phân cách nhau bằng dấu chấm .
. Dưới đây là cấu trúc cơ bản của một chuỗi JWT:
eyJraWQiOiIyNTg4NzYyMy1iNjljLTQ0ODEtYjQ3Ni1lNTk3MTdlZjg4ZGQiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsInN1YiI6IndpZW5lciIsImV4cCI6MTY4Mzk1MzczNn0.yTR_bNCN4prjtvhkPy43n1CI93EOyxCP-xWtAgOrGSoIo0q2-nYhisGh5k0o-IfqlJGt6QrYSXykjvej_0_1WndSHUcv5rsC3b--37wyyNnyzVP3o37fFZOVxaLk6zpdpxeSJPmz0L1j1rCDeJqU73tIjpmwTulrxNq5zx-sO-AnopHaFzIfletzBAFQtrKETwaWc6rUtzVIL5BnkSTsrnQMFevg57CxfD8Qqvsu-ePfEPJ4xcmhSJcQLuriVUNmkFLmpGO2WRnrCgyga4uCIde0cdNsYN7UBrKs9E8akGxUU_HbRwmrBKaTzPDKrxQeV7nsb6TZOOexS0cFx7cJwg
3.1. Header
Header chứa thông tin về loại token và thuật toán mã hóa được sử dụng để tạo ra chữ ký. Nó được mã hóa bằng Base64 và thường có hai thuộc tính chính là alg (thuật toán) và typ (loại). Ví dụ:
{
"kid":"25887623-b69c-4481-b476-e59717ef88dd",
"alg":"RS256",
"typ": "JWT"
}
3.2. Payload
Payload chứa thông tin về người dùng hoặc ứng dụng mà token đại diện, cũng được mã hóa bằng Base64. Nội dung payload có thể bao gồm nhiều thuộc tính như iss
(người phát hành), sub
(chủ sở hữu), aud
(đối tượng sử dụng), và exp
(thời gian hết hạn). Ví dụ về payload:
{
"iss":"viblosecurity",
"sub":"11d3-ae19-be29-8020",
"admin": false,
"email": "user.test@viblo-security.com",
"exp":1683953736
}
3.3. Signature
Signature được tạo ra bằng cách kết hợp header và payload với một Secret Key thông qua một thuật toán hash như HMAC hoặc RSA. Signature giúp đảm bảo tính toàn vẹn của JWT và xác nhận rằng dữ liệu trong payload không bị chỉnh sửa.
4. Khi nào nên sử dụng JWT?
JWT thích hợp cho nhiều tình huống trong ứng dụng web và dịch vụ:
4.1. Xác thực Người Dùng
JWT thường được sử dụng để xác thực người dùng khi đăng nhập, với thông tin được gửi trong header của yêu cầu đến máy chủ.
4.2. Quản lý Tài Khoản
Nó cũng có thể được sử dụng để quản lý tài khoản của người dùng thông qua việc lưu trữ thông tin trong payload.
4.3. Trao đổi Thông Tin
JWT thuận tiện trong việc truyền tải thông tin giữa các ứng dụng mà không cần xác thực lại mỗi lần.