在Spring Boot中实现无感刷新Token,通常是为了在Token即将过期时自动更新,从而避免用户需要重新登录,提升用户体验。以下是一种基于双Token(Access Token和Refresh Token)机制的实现方法:
一、双Token机制概述Access Token:用于日常请求的身份验证,有效期较短,如1小时。Refresh Token:用于在Access Token过期后获取新的Access Token,有效期较长,如1个月。二、实现步骤1. 生成Token使用JWT(Json Web Tokens)来生成Token,并在其中设置过期时间。可以创建一个JWT工具类,如JwtUtil,用于生成Access Token和Refresh Token。
@Component public 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(); } }2. 拦截器处理在Spring Boot中,通过拦截器来检查Access Token是否即将过期,并自动使用Refresh Token获取新的Access Token。可以创建一个JWT请求过滤器,如JwtRequestFilter。
@Component public 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); } }3. 前端处理在前端,需要监听Token的变化,并在新的Access Token获取后更新本地存储的Token。这可以通过WebSocket、轮询或HTTP响应头来实现。
三、注意事项Refresh Token的安全性:Refresh Token应设置较长的过期时间,但也需要有失效机制,防止长期未使用导致的安全隐患。Refresh Token的存储应比Access Token更安全,避免在客户端存储明文。异常处理:在实际应用中,需要考虑Token刷新失败、网络异常等情况的处理,确保系统的健壮性。日志记录:记录Token刷新的相关日志,以便于问题排查和审计。通过以上步骤,可以在Spring Boot中实现无感刷新Token,提升用户体验,并确保系统的安全性。