1. 理解Token过期与无感刷新
Token过期是指Token在达到设定的有效时间后被系统判定为无效,再次使用时会返回401错误。无感刷新Token则是指在不干扰用户正常操作的情况下,自动更新即将过期的Token,避免用户被迫重新登录。
2. 双Token机制
实现无感刷新Token的一种常见策略是采用双Token机制,即Access Token和Refresh Token。
- Access Token:用于日常请求的身份验证,有效期较短,例如1小时。
- Refresh Token:用于在Access Token过期后获取新的Access Token,有效期较长,例如1个月。
3. 实现步骤
3.1 生成Token
首先,需要实现Token的生成逻辑。可以使用JWT(Json Web Tokens)来生成Token,并在其中设置过期时间。
java复制代码 @Component public class JwtUtil { private String secret = "your-secret-key"; public String generateAccessToken(UserDetails userDetails) { return Jwts.builder() .setSubject(userDetails.getUsername()) .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1小时有效期 .signWith(SignatureAlgorithm.HS512, secret) .compact(); } public String generateRefreshToken(UserDetails userDetails) { return Jwts.builder() .setSubject(userDetails.getUsername()) .setExpiration(new Date(System.currentTimeMillis() + 2592000000)) // 30天有效期 .signWith(SignatureAlgorithm.HS512, secret) .compact(); } }
3.2 拦截器实现
在SpringBoot中,可以通过拦截器来检查Access Token是否即将过期,并自动使用Refresh Token获取新的Access Token。
java复制代码 @Component public class JwtRequestFilter extends OncePerRequestFilter { @Autowired private JwtUtil jwtUtil; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String token = request.getHeader("Authorization"); if (token != null && jwtUtil.isTokenAboutToExpire(token)) { // 使用Refresh Token获取新的Access Token // 这里需要实现与客户端的交互,例如通过WebSocket或轮询 // 假设已经获取到了新的Access Token String newAccessToken = jwtUtil.refreshAccessToken(...); // 设置新的Access Token到响应头或Session中 } chain.doFilter(request, response); } }
注意:这里的isTokenAboutToExpire
和refreshAccessToken
方法需要具体实现,refreshAccessToken
方法可能涉及到与客户端的交互。
3.3 前端处理
在前端,需要监听Token的变化,并在新的Access Token获取后更新本地存储的Token。这可以通过WebSocket、轮询或HTTP响应头来实现。
3.4 安全性考虑
- Refresh Token的存储应比Access Token更安全,避免在客户端存储明文。
- Refresh Token应设置较长的过期时间,但也需要有失效机制,防止长期未使用导致的安全隐患。
- 对于敏感操作,可能需要用户重新登录或进行二次验证。
4. 总结
通过双Token机制和拦截器的实现,SpringBoot可以做到无感刷新Token,提升用户体验。然而,在实际应用中,还需要考虑安全性、异常处理、日志记录等多个方面,确保系统的健壮性和用户体验。