Tìm hiểu về cách JWT hoạt động
Và cách JWT bảo vệ API của bạn
Ví dụ thực tế
Hãy hình dung bạn đi xem phim. Bạn mua vé online, khi đến rạp bạn đưa mã đặt vé cho nhân viên thu ngân. Họ kiểm tra mã trên hệ thống bán vé, xác nhận hợp lệ và in vé cho bạn.
Trong lúc xem phim, bạn ra ngoài mua thêm bắp nước. Khi quay lại cổng, bạn không cần trình lại mã mua vé để nhân viên tra cứu hệ thống nữa. Thay vào đó, chỉ cần đưa tấm vé đã in, nhân viên nhìn vào là biết hợp lệ và cho bạn vào lại.
JWT hoạt động tương tự:
Xác thực một lần khi đăng nhập
Dùng lại token cho các request tiếp theo
JWT là gì?
JWT là viết tắt của JSON Web token. Một đoạn code nhỏ gọn dùng để xác thực người dùng. Nó thường được đính kiêm trong header của HTTP request với dạng:
Authorization: Bearer <JWT>Luồng dữ liệu sẽ trông thế này
Authentication: Người dùng cung cấp user/password cho server.
Token Generation & sending token to client: Server sẽ tạo một JWT token sau đó sẽ gửi cho client để sử dụng cho những lần sau. Lưu ý, server sẽ không cần lưu token này lại
Sending the Token to server: Khi client nhận được token, client sẽ lưu lai ở cookies hay local storage. Khi client muốn truy cập một API được bảo vệ, client sẽ gửi HTTP request đính kèm JWT đã lưu vào phần header của request.
Verifying the Token: Server nhận được token từ client, sao đó sẽ validate token,
Authorizing the Request nếu token valid sẽ trả về response của request client cần truy cập. Nếu token không hợp hệ sẽ trả về lỗi 401 Unauthorized
Quá trình tạo và xác nhận JWT như thế nào?
JWT token thường gồm 3 phần, cách nhau bằng dấu chấm (.)
Header
Payload
Signature
Format của JWT sẽ như thế này:
xxxxx.yyyyy.zzzzzHeader
Phần header thường gồm 2 phần nhỏ, thuật toán dùng để ký và loại token. Ví dụ một header của JWT:
{
"alg": "HS256",
"typ": "JWT"
}Nội dung của phần này sau đó được encode bằng Base64Url encoded.
Payload
Phần thứ hai thường chứ thông tin về đối tượng sử dụng JWT, ví dụ như họ tên, địa chỉ và thời gian token hết hạn. Ví dụ:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}Thông tin sẽ được encode bằng thuật toán Base64Url tương tự như phần header.
Signature
Phần cuối sẽ là chữ ký, nó sẽ đảm bảo rằng nội dung của JWT không bị chỉnh sửa. Ví dụ nếu chúng ta sử dụng thuật toán HMACSHA256, chữ ký sẽ được toạ bằng cách.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)Putting all together
Cả 3 đoạn Base64-URL strings sẽ được gộp lại với nhau và phân tách bằng dấu chấm (.). Ví dụ một JWT token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30Bạn có thể debug bằng cách copy/paste đoạn JWT vô https://www.jwt.io
Ví dụ bằng Python
Đầu tiên chúng ta phải cài đặt thư viện python-jose
pip install python-jose[cryptography]from jose import JWTError, jwt
from datetime import datetime, timedelta
# Secret key & thuật toán
SECRET_KEY = "super-secret-key" # Thực tế nên lưu trong biến môi trường
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
# Hàm tạo JWT token
def create_access_token(data: dict, expires_delta: timedelta | None = None):
to_encode = data.copy()
expire = datetime.utcnow() + (expires_delta or timedelta(minutes=15))
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwtCách xác thực JWT
Sau khi nhận được token, server sẽ sử dụng đúng thuật toán ở phần header kèm với khoá bí mật để ký lúc tạo token. Tính toán lại chữ ký dự trên encode payload và header. Sau đó so sánh với chữ ký ở JWT gửi lên từ client. Nếu chúng khớp có nghĩa là JWT hợp lệ và chưa bị chỉnh sửa. Bạn có thể tìm hiểu thêm về thuật toán chữ ký số ở post trước của mình về chữ ký điện tử (https://substack.com/home/post/p-169813200)
Sau khi phần chữ ký hợp lệ, server tiếp tục validate phần nội dung ở phần payload. Ví dụ như JWT vẫn chưa hết hạn. Hoặc thời gian hiện tại không trước khi thời gian tạo token.
Nếu sau đó token vẫn hợp hệ, hệ thống sẽ trả về thông báo cho phép user truy cập tài nguyên.
Ví dụ cách verify JWT bằng Python
def verify_token(token: str):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid token")
return username
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")Kết luận
Qua bài viết này, bạn đã nắm được cách tạo JWT và cơ chế hoạt động của nó trong việc xác thực (authentication) và phân quyền (authorization). Hy vọng những kiến thức này sẽ giúp bạn xây dựng hệ thống an toàn và hiệu quả hơn.
Nếu có thắc mắc, đừng ngần ngại để lại câu hỏi.
Chúc bạn học tập vui vẻ! 🚀
Đọc thêm:
https://www.jwt.io/introduction#what-is-json-web-token
https://substack.com/home/post/p-169813200
https://pypi.org/project/python-jose/




Các áp dụng vào prj thực tết ntn vậy bạn?