JWT là gì?
JWT (JSON Web Token) là một chuỗi mã hoá chứa thông tin người dùng. Server tạo JWT khi đăng nhập thành công, gửi về client. Client gửi JWT kèm mỗi request sau đó để chứng minh danh tính — server không cần lưu session.
// File: jwt-structure.txt
// JWT gồm 3 phần, ngăn bởi dấu chấm:
header.payload.signature
// Header: thuật toán và loại token
{ "alg": "HS256", "typ": "JWT" }
// Payload: dữ liệu người dùng (claims)
{ "userId": "u1", "role": "student", "exp": 1691000000 }
// Signature: chữ ký xác thực
HMACSHA256(base64(header) + "." + base64(payload), SECRET_KEY)
⚠ JWT KHÔNG mã hoá
Payload chỉ được encode base64 — ai cũng đọc được. KHÔNG đặt mật khẩu, thông tin nhạy cảm trong payload. Signature chỉ đảm bảo payload chưa bị sửa, không đảm bảo bí mật.
Triển khai đăng nhập với JWT
// File: auth.js
import jwt from 'jsonwebtoken'
import bcrypt from 'bcryptjs'
const ACCESS_SECRET = process.env.JWT_ACCESS_SECRET
const REFRESH_SECRET = process.env.JWT_REFRESH_SECRET
// Đăng nhập: kiểm tra mật khẩu → tạo token
async function login(email, password) {
const user = await db.users.findByEmail(email)
if (!user) throw new Error("Email không tồn tại")
const valid = await bcrypt.compare(password, user.passwordHash)
if (!valid) throw new Error("Sai mật khẩu")
// Access token: ngắn hạn (15 phút)
const accessToken = jwt.sign(
{ userId: user.id, role: user.role },
ACCESS_SECRET,
{ expiresIn: "15m" }
)
// Refresh token: dài hạn (7 ngày)
const refreshToken = jwt.sign(
{ userId: user.id },
REFRESH_SECRET,
{ expiresIn: "7d" }
)
return { accessToken, refreshToken }
}
Middleware xác thực
// File: middleware.js
// Middleware kiểm tra token trước mỗi request cần auth
function authMiddleware(req, res, next) {
const header = req.headers['authorization']
if (!header?.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Thiếu token' })
}
const token = header.split(' ')[1]
try {
const decoded = jwt.verify(token, ACCESS_SECRET)
req.user = decoded
next()
} catch {
return res.status(401).json({ error: 'Token hết hạn hoặc không hợp lệ' })
}
}
| Loại token | Thời hạn | Lưu ở đâu | Khi hết hạn |
|---|---|---|---|
| Access token | 15 phút | Memory / localStorage | Dùng refresh token để lấy cái mới |
| Refresh token | 7 ngày | httpOnly cookie | Đăng nhập lại |
❓ Vì sao access token nên có thời hạn ngắn (15 phút)?
- Giải thích cấu trúc 3 phần của JWT
- Tạo access token và refresh token
- Viết middleware xác thực Bearer token
- Biết không đặt dữ liệu nhạy cảm trong payload