共计 1456 个字符,预计需要花费 4 分钟才能阅读完成。
真实案例:Token 管理不当的代价
去年某社交平台因 Access Token 有效期设置为 30 天且未启用 Refresh Token 机制,导致攻击者通过 XSS 漏洞窃取的 Token 可长期有效。更严重的是某金融系统使用 JWT 时未校验 exp 字段,使得已注销 Token 仍能访问敏感接口。

JWT vs OAuth2 有效期设计对比
| 特性 | JWT | OAuth2 |
|---|---|---|
| 过期控制 | 内置 exp 字段 |
服务端存储过期时间 |
| 强制失效 | 需维护黑名单 | 直接删除服务端记录 |
| 续期方式 | 重新签发完整 Token | 通过 Refresh Token 静默更新 |
| 时钟同步依赖 | 严重依赖 | 无依赖 |
Spring Security 核心实现
@EnableWebSecurity
public class TokenConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(
new TokenRefreshFilter(tokenStore(),
userRiskCalculator() // 注入用户风险等级计算器),
UsernamePasswordAuthenticationFilter.class
);
}
// 动态过期时间算法示例
public Duration calculateExpiry(UserRiskLevel riskLevel) {return switch (riskLevel) {case HIGH -> Duration.ofMinutes(15);
case MEDIUM -> Duration.ofHours(1);
case LOW -> Duration.ofDays(7);
};
}
}
Token 续期流程图
sequenceDiagram
Client->>+AuthServer: 携带过期 Token 请求刷新
AuthServer->>+Redis: 检查 Token 黑名单
Redis-->>-AuthServer: 返回校验结果
alt 未过期且未列入黑名单
AuthServer->>+DB: 读取用户风险等级
DB-->>-AuthServer: 返回风险数据
AuthServer->>AuthServer: 计算新过期时间
AuthServer-->>-Client: 返回新 Token
else 已过期或无效
AuthServer-->>-Client: 返回 401 错误
end
生产环境关键要点
- 时钟漂移应对:部署 NTP 时间同步服务,JWT 校验时增加 5 分钟缓冲期
- 分布式同步:采用 Redis Pub/Sub 机制广播黑名单变更事件
- 并发控制:使用 Redis 原子操作实现 Token 刷新锁
// 基于 Redis 的刷新锁实现 Boolean locked = redisTemplate.opsForValue() .setIfAbsent("lock:refresh:"+userId, "1", 10, TimeUnit.SECONDS); - 黑名单清理:定时任务按 TTL 分批清理,避免全表扫描
开放性问题思考
- 无感刷新可能引入的中间人攻击风险如何防范?
- 当 Refresh Token 被盗用时,如何平衡安全性与用户体验?
- 生物认证是否可以作为 Refresh Token 的替代方案?
经验总结
在实际项目中,我们采用分级 Token 策略:高危操作要求 15 分钟短时效 Token 配合二次认证,后台管理采用 4 小时时效 + 行为分析动态调整。关键发现是:单纯缩短有效期会显著增加系统负载,需要配合完善的监控体系才能实现安全与性能的平衡。
正文完
