JWT鉴权机制实现方法与要点

实现 JWT(JSON Web Token)鉴权机制是现代 Web 应用中常见的安全策略,用于在客户端和服务器之间安全地传输信息。以下是实现 JWT 鉴权机制的基本思路和步骤:
1. 用户登录
- 客户端:用户通过登录表单提交用户名和密码。
- 服务器:验证用户名和密码。如果验证成功,服务器生成一个 JWT。
2. 生成 JWT
- 服务器:使用用户的唯一标识(如用户ID)和一些元数据(如过期时间)作为 payload,使用一个密钥(secret key)进行签名,生成 JWT。
- Payload 示例:
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022, "exp": 1516242622 }
- 签名:使用 HMAC SHA256 算法签名,生成 JWT。
const jwt = require('jsonwebtoken'); const token = jwt.sign(payload, 'your-secret-key', { expiresIn: '1h' });
3. 返回 JWT 给客户端
- 服务器:将生成的 JWT 返回给客户端,通常通过 HTTP 响应体或头部的
Authorization
字段。{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }
4. 客户端存储 JWT
- 客户端:将收到的 JWT 存储在本地存储(localStorage)或会话存储(sessionStorage)中,或者作为 cookie 存储。
5. 客户端发送请求时携带 JWT
- 客户端:在每次请求时,将 JWT 放在 HTTP 请求头的
Authorization
字段中。Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
6. 服务器验证 JWT
- 服务器:在接收到请求时,从
Authorization
头中提取 JWT,并使用相同的密钥验证 JWT 的签名和有效期。const jwt = require('jsonwebtoken'); const token = req.headers['authorization'].split(' ')[1]; try { const decoded = jwt.verify(token, 'your-secret-key'); req.user = decoded; next(); } catch (err) { res.status(401).json({ message: 'Invalid token' }); }
7. 授权访问
- 服务器:如果 JWT 验证成功,服务器允许访问受保护的资源;如果验证失败,返回 401 Unauthorized 错误。
8. 刷新 JWT
- 客户端:在 JWT 即将过期时,客户端可以请求服务器刷新 JWT,生成一个新的 JWT 并返回给客户端。
9. 注销和黑名单
- 服务器:如果需要实现注销功能,可以将 JWT 加入黑名单(如存储在 Redis 中),并在每次请求时检查 JWT 是否在黑名单中。
10. 安全性考虑
- HTTPS:确保所有通信通过 HTTPS 进行,防止 JWT 被窃取。
- 短有效期:设置较短的 JWT 有效期,减少被盗用的风险。
- 刷新令牌:使用刷新令牌机制,减少 JWT 的暴露时间。
示例代码
以下是一个简单的 Express.js 示例,展示如何实现 JWT 鉴权:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const SECRET_KEY = 'your-secret-key';
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 验证用户名和密码
if (username === 'admin' && password === 'password') {
const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
} else {
res.status(401).json({ message: 'Invalid credentials' });
}
});
app.get('/protected', (req, res) => {
const token = req.headers['authorization']?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'No token provided' });
jwt.verify(token, SECRET_KEY, (err, decoded) => {
if (err) return res.status(401).json({ message: 'Invalid token' });
res.json({ message: 'Protected data', user: decoded });
});
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
通过以上步骤和示例代码,你可以实现一个基本的 JWT 鉴权机制。根据具体需求,你可以进一步优化和扩展这个机制。