JWT (JSON Web Token) 验证接口
以下是标准的 JWT (JSON Web Token) 验证接口 的实现示例,包括 生成 Token、验证 Token 和 刷新 Token 的核心逻辑,适用于大多数 Web 框架(如 Express.js、Spring Boot、Django 等)。
1. JWT 验证接口设计
接口功能
- 生成 Token:用户登录后签发 JWT
- 验证 Token:保护需要认证的接口
- 刷新 Token:当 Token 快过期时刷新
依赖库
- 推荐使用
jsonwebtoken(Node.js)、jjwt(Java)、PyJWT(Python) - 需要密钥(
SECRET_KEY)和过期时间配置
2. 代码实现示例(Node.js + Express)
(1) 生成 Token
javascript
const jwt = require('jsonwebtoken');
const SECRET_KEY = 'your-secret-key'; // 实际项目中应使用环境变量存储
const EXPIRES_IN = '1h'; // Token 有效期
// 登录接口:生成 Token
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 1. 验证用户名密码(模拟)
if (username !== 'admin' || password !== '123456') {
return res.status(401).json({ error: 'Invalid credentials' });
}
// 2. 生成 JWT
const payload = { userId: 1, username: username };
const token = jwt.sign(payload, SECRET_KEY, { expiresIn: EXPIRES_IN });
res.json({ token });
});(2) 验证 Token(中间件)
javascript
// JWT 验证中间件
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // Bearer <token>
if (!token) return res.status(401).json({ error: 'Missing token' });
jwt.verify(token, SECRET_KEY, (err, user) => {
if (err) return res.status(403).json({ error: 'Invalid or expired token' });
req.user = user; // 将解码后的用户信息附加到请求对象
next();
});
}
// 受保护的路由
app.get('/protected', authenticateToken, (req, res) => {
res.json({ message: `Hello, ${req.user.username}!` });
});(3) 刷新 Token
javascript
app.post('/refresh-token', (req, res) => {
const { token } = req.body;
if (!token) return res.status(401).json({ error: 'Token required' });
jwt.verify(token, SECRET_KEY, (err, user) => {
if (err) return res.status(403).json({ error: 'Invalid token' });
// 检查 Token 是否快过期(例如剩余时间 < 15分钟)
const decoded = jwt.decode(token);
const now = Math.floor(Date.now() / 1000);
if (decoded.exp - now > 900) { // 15分钟 = 900秒
return res.status(400).json({ error: 'Token not expired yet' });
}
// 生成新 Token(移除旧 Token 的过期时间)
const newToken = jwt.sign({ userId: user.userId, username: user.username }, SECRET_KEY, { expiresIn: EXPIRES_IN });
res.json({ token: newToken });
});
});3. 关键安全注意事项
密钥管理:
- 永远不要将
SECRET_KEY硬编码在代码中,使用环境变量(如process.env.JWT_SECRET)。 - 定期轮换密钥(如每 3 个月)。
- 永远不要将
Token 存储:
- 客户端:建议存于
HttpOnlyCookie 或localStorage(需防范 XSS)。 - 服务端:可结合 Redis 实现 Token 黑名单(用于注销)。
- 客户端:建议存于
防止 CSRF:
- 如果使用 Cookie,需配合 CSRF Token。
过期时间:
- 访问令牌(Access Token):建议短(如 15分钟~1小时)
- 刷新令牌(Refresh Token):可较长(如 7天),但需安全存储
4. 其他语言示例
Java (Spring Boot)
java
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
// 生成 Token
String token = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1小时
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
// 验证 Token
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();Python (Django/Flask)
python
import jwt
# 生成 Token
token = jwt.encode({'user_id': 1, 'exp': datetime.utcnow() + timedelta(hours=1)}, SECRET_KEY, algorithm='HS256')
# 验证 Token
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
except jwt.ExpiredSignatureError:
return {"error": "Token expired"}5. 测试工具(Postman)
- 登录接口:
POST /login→ 获取 Token - 访问受保护接口:在 Headers 中添加:
Authorization: Bearer <your-token>
如果需要针对特定框架或场景的详细实现,请告知您的技术栈(如 Spring Security、Django REST Framework 等)。
