前端鉴权体系:JWT与Refresh Token的设计与实践
在前端鉴权体系中,JWT(JSON Web Token)和Refresh Token是常见的组合,用于实现安全的用户认证和授权机制。以下是一个基于JWT和Refresh Token的鉴权体系设计,涵盖过期策略和实践。
1. JWT 过期策略
JWT通常包含一个过期时间(exp
),用于控制Token的有效期。过期策略的设计需要考虑以下几点:
- 短期有效:JWT的有效期应尽可能短(如15分钟到1小时),以减少Token泄露后的风险。
- 无状态:JWT是无状态的,服务器不需要存储Token信息,验证时只需通过签名验证其合法性。
JWT 结构示例:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622 // 过期时间
}
2. Refresh Token 机制
Refresh Token用于在JWT过期后获取新的JWT,通常具有较长的有效期(如7天到30天)。Refresh Token的机制设计如下:
- 长期有效:Refresh Token的有效期较长,但应定期轮换。
- 安全存储:Refresh Token应存储在安全的HTTP-only Cookie中,防止XSS攻击。
- 单点登录(SSO):Refresh Token可以用于实现单点登录,用户只需登录一次即可在多个系统中保持登录状态。
Refresh Token 结构示例:
{
"sub": "1234567890",
"jti": "unique-refresh-token-id",
"exp": 1516843822 // 过期时间
}
3. 鉴权流程
-
用户登录:
- 用户提交用户名和密码。
- 服务器验证成功后,生成JWT和Refresh Token,并返回给客户端。
-
JWT 使用:
- 客户端在每次请求时携带JWT(通常放在
Authorization
头中)。 - 服务器验证JWT的签名和有效期,如果有效则处理请求。
- 客户端在每次请求时携带JWT(通常放在
-
JWT 过期:
- 当JWT过期时,客户端使用Refresh Token请求新的JWT。
- 服务器验证Refresh Token的有效性,如果有效则生成新的JWT并返回给客户端。
-
Refresh Token 过期:
- 当Refresh Token过期时,用户需要重新登录。
4. 安全实践
- HTTPS:确保所有通信通过HTTPS进行,防止中间人攻击。
- Token 存储:JWT可以存储在内存或LocalStorage中,但Refresh Token应存储在HTTP-only Cookie中。
- Token 轮换:每次使用Refresh Token获取新的JWT时,生成新的Refresh Token并废弃旧的,防止Token泄露后被滥用。
- 黑名单机制:在必要时,可以维护一个Token黑名单,用于撤销特定的Token。
5. 代码示例
生成 JWT 和 Refresh Token
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
function generateTokens(user) {
const accessToken = jwt.sign(
{ sub: user.id, name: user.name },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ sub: user.id, jti: crypto.randomBytes(16).toString('hex') },
process.env.REFRESH_SECRET,
{ expiresIn: '7d' }
);
return { accessToken, refreshToken };
}
验证 JWT
function verifyAccessToken(token) {
try {
return jwt.verify(token, process.env.JWT_SECRET);
} catch (err) {
return null;
}
}
使用 Refresh Token 获取新的 JWT
function refreshAccessToken(refreshToken) {
try {
const payload = jwt.verify(refreshToken, process.env.REFRESH_SECRET);
const newAccessToken = jwt.sign(
{ sub: payload.sub, name: payload.name },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
return newAccessToken;
} catch (err) {
return null;
}
}
6. 总结
通过JWT和Refresh Token的组合,可以实现一个安全、高效的鉴权体系。JWT的短期有效性和无状态特性确保了系统的安全性和可扩展性,而Refresh Token的长期有效性和安全存储机制则提供了良好的用户体验和安全性。在实际应用中,还需结合具体业务场景和安全需求,进一步优化和调整鉴权策略。