SpringBoot 整合 JWT——Token 认证与自动刷新

发布时间:2026/7/19 0:44:14
SpringBoot 整合 JWT——Token 认证与自动刷新 Session 方式在分布式环境下不好用JWTJSON Web Token是目前主流的无状态认证方案。服务端不需要存 SessionToken 中包含了用户信息。一、JWT 结构header.payload.signature header: 加密算法 payload: 用户数据不要放密码 signature: 签名防止篡改二、JWT 工具类ComponentpublicclassJwtUtil{Value(${jwt.secret:mySecretKey})privateStringsecret;Value(${jwt.expire:86400000})privatelongexpire;// 默认24小时publicStringgenerateToken(LonguserId,Stringusername){DatenownewDate();returnJwts.builder().setSubject(userId.toString()).claim(username,username).setIssuedAt(now).setExpiration(newDate(now.getTime()expire)).signWith(SignatureAlgorithm.HS256,secret).compact();}publicClaimsparseToken(Stringtoken){returnJwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}publicbooleanvalidateToken(Stringtoken){try{parseToken(token);returntrue;}catch(Exceptione){returnfalse;}}}三、登录接口RestControllerRequestMapping(/auth)publicclassAuthController{AutowiredprivateJwtUtiljwtUtil;PostMapping(/login)publicResultVOMapString,Objectlogin(RequestParamStringusername,RequestParamStringpassword){// 校验用户名密码if(!admin.equals(username)||!123456.equals(password)){returnResultVO.error(401,用户名或密码错误);}// 生成 TokenStringaccessTokenjwtUtil.generateToken(1001L,username);StringrefreshTokenjwtUtil.generateRefreshToken(1001L);MapString,ObjectresultnewHashMap();result.put(accessToken,accessToken);result.put(refreshToken,refreshToken);result.put(expiresIn,86400);returnResultVO.success(result);}}四、Token 刷新PostMapping(/refresh)publicResultVOMapString,Objectrefresh(RequestParamStringrefreshToken){if(!jwtUtil.validateToken(refreshToken)){returnResultVO.error(401,RefreshToken 无效);}ClaimsclaimsjwtUtil.parseToken(refreshToken);LonguserIdLong.parseLong(claims.getSubject());Stringusernameclaims.get(username,String.class);StringnewAccessTokenjwtUtil.generateToken(userId,username);StringnewRefreshTokenjwtUtil.generateRefreshToken(userId);returnResultVO.success(Map.of(accessToken,newAccessToken,refreshToken,newRefreshToken));}五、拦截器校验ComponentpublicclassJwtInterceptorimplementsHandlerInterceptor{AutowiredprivateJwtUtiljwtUtil;OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{Stringtokenrequest.getHeader(Authorization);if(tokennull||!token.startsWith(Bearer )){thrownewBusinessException(401,未登录);}tokentoken.substring(7);if(!jwtUtil.validateToken(token)){thrownewBusinessException(401,Token 已过期);}// 将用户信息存入请求上下文ClaimsclaimsjwtUtil.parseToken(token);request.setAttribute(userId,claims.getSubject());request.setAttribute(username,claims.get(username));returntrue;}}六、前端调用// 登录constrespawaitfetch(/auth/login,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify({username:admin,password:123456})});const{accessToken,refreshToken}awaitresp.json();// 后续请求携带 Tokenfetch(/api/user,{headers:{Authorization:Bearer accessToken}});// Token 过期时用 refreshToken 刷新asyncfunctionrefreshAccessToken(){constrespawaitfetch(/auth/refresh,{method:POST,body:newURLSearchParams({refreshToken})});constdataawaitresp.json();accessTokendata.accessToken;}七、安全注意事项// 1. JWT 中不要放敏感信息ClaimsclaimsJwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();Stringpasswordclaims.get(password);// ❌ 错误// 2. 密钥不要写死用配置中心或环境变量Value(${jwt.secret})privateStringsecret;// 3. accessToken 有效期短15-30分钟// refreshToken 有效期长7天专门用来刷新 accessToken总结Session 认证服务端存 Session分布式下需要共享 Session JWT 认证 无状态Token 携带用户信息适合分布式 JWT 缺点签发后无法主动失效只能等过期 解决方案accessToken 短时效 refreshToken 刷新机制 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。