1. Json Web Token (JWT) là gì?
JWT là một tiêu chuẩn mở RFC 7519, được sử dụng như một người đại diện để trao đổi thông tin một cách an toàn giữa server và client thông qua một chuỗi JSON. Thông tin giao dịch thông qua JWT sẽ được bảo mật và có độ tin tưởng cao nhờ vào chữ ký điện tử để xác minh tính toàn vẹn sở hữu. Chữ ký điện tử sử dụng mã khóa công khai/ riêng tư sử dụng RSA, ECDSA với thuật toán HMAC.
Một JWT thường có dạng như sau:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiIxOCIsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMn0.wLlRl9-4bZ_w_ueEVCkACKFj7PJp7dewAX-bfnYujpc
Một JWT sẽ chia thành 3 phần (HEADER, PAYLOAD, VERIFY SIGNATURE) cách nhau bởi dấu ".":
- HEADER: Phần chứa thuật toán mã hoá sử dụng ví dụ: HS256, HS512,... và token type.
- PAYLOAD: Phần chứa data.
- VERIFY SIGNATURE: Chữ ký xác minh.
2. Cơ chế xác thực của client và server hoạt động như thế nào?
Mô tả: Khi client đăng nhập sẽ gửi thông tin đăng nhập xuống server -> server xác thực nếu thông tin hợp lệ sẽ tạo ra token gửi lại cho client -> client giữ token để mỗi lần request sẽ gửi kèm token để server xác thực.
3. Code demo cơ chế đăng nhập tạo token và xác thực token với nodejs
Login
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken'; const login = async (req: Request, res: Response) => { const { email, password } = req.body; const condition = { email, status: 'active', }; const account = await Account.findOne(condition); if (!account) { return res.status(400).json({ message: 'Account has been locked'}) } const isValidPassword = await bcrypt.compare(password, account.password); if (isValidPassword) { const payload = { _id: account._id, email: account.email, displayName: account.displayName, role: account.role, }; return jwt.sign(payload, environment.jwt.secretKey); } return res.status(400).json({ message: 'Invalid login info'});
};
Verify token
import jwt from 'jsonwebtoken'; const auth = async (req: Request, res: Response, next: NextFunction) => { const token = req.headers.authorization?.split(' '); if (!token) { return res.status(400).json({ message: 'Token not found'}) } try { const payload = jwt.verify(token[1], environment.jwt.secretKey); req.account = account; return next(); } catch (error) { return res.status(400).json({ message: 'Invalid token'}) }
}
4. Khi nào nên dùng JWT?
- Xác thực: phần lớn người dùng sử dụng JWT dùng để xác thực sau khi đăng nhập thành công, để tăng mức độ tiện dụng trong những lần xác thực kế tiếp cũng như tăng cường sự an toàn bảo mật.
- Trao đổi, truyền đạt thông tin: để trao đổi thông tin an toàn giữa các bên thì JWT cũng là 1 giải pháp, phần signature (chữ ký) ở JWT cho phép bạn xác minh và định danh người gửi, dễ dàng phát hiện nếu có giả mạo. Bên cạnh đó cấu trúc JWT cũng giúp bạn biết nội dung đó có chính xác không.
5. Lời kết
Đây là bài viết đầu tiên của mình tại viblo. Hy vọng qua những chia sẻ của mình sẽ giúp được cho bạn hiểu thêm được những thông tin cơ bản JWT và cơ chế xác thực của server và client hoạt động như thế nào. Quan điểm của mình không có gì là hoàn hảo cả, giả sử trong trường hợp JWT của bạn bị đánh cắp thì lúc này kẻ đánh cắp vẫn có thể hoàn toàn sử dụng JWT của bạn, vì thế để giảm thiểu khả năng thiệt hại JWT thường luôn có thời hạn sử dụng ở khoảng thời gian ngắn, sau khoảng thời gian trên mã JWT sẽ không còn hiệu lực. Với những thông tin trên hy vọng có thể giúp các bạn sử dụng JWT một cách hiệu quả nhất cho nghiệp vụ của mình, các bạn có thể tìm hiểu thêm thông tin tại trang chủ của jwt: https://jwt.io/
Cảm ơn vì đã ghé ngang và đọc bài viết ♥️