文章目录
- 前言
- 一、使用步骤
-
- 1.实体user
- 2.登录AuthController
- 3.网关GatewayFilter
- 4.续约TokenService
- 总结
前言
在系统中,在 token 的有效期内,可以登录使用,并且要求如果一直使用系统,一直保持登录状态,而不是 token 过期就直接退出系统了,所以需要在操作系统时保持对 token 有效期的续期。
本文是以 gateway 网关过滤器功能实现。
一、使用步骤
1.实体user
- 在用户的实体类中添加如下几个字段
private Integer expireTime; // 登录超时时间,单位min,此为数据库存的,用户可以自由设置过期时间(按需操作) private Long loginTime; // 登录时间 private Long failureTime; // 过期时间 private String token; // 用户唯一标识
2.登录AuthController
public class AuthController { private static final long MILLIS_SECOND = 1000; private static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; @Autowired private RedisUtil redisUtil; @PostMapping("/login") public R login( HttpServletRequest request, @RequestBody AuthUser user){ // 验证用户名密码、验证码、登录次数、禁用账号等代码省略... // userEntity为数据库查询出来的用户信息 // 登录超时时间,数据库获取,如无此需求,可规定 30min过期即可 Integer expireTime = userEntity.getExpireTime(); userEntity.setLoginTime(System.currentTimeMillis()); userEntity.setFailureTime(userEntity.getLoginTime() + expireTime * MILLIS_MINUTE); userEntity.setToken(request.getSession().getId()); // 使用uuid等唯一标识即可 //放入缓存 redisUtil.set("token_" + request.getSession().getId(), JSON.toJSONString(userEntity), expireTime, TimeUnit.MINUTES); return R.ok().setObj(request.getSession().getId()); } }
3.网关GatewayFilter
- 其中一些代码已省略,只保存了续约token的代码:tokenService.verifyToken(user);
@Slf4j @Order(-1) // 保证请求必经此代码 @Component public class GatewayFilter implements GlobalFilter { @Autowired private TokenService tokenService; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { HttpHeaders headers = exchange.getRequest().getHeaders(); List<String> tokenList = headers.get("Access-Token"); ServerHttpRequest request = exchange.getRequest(); String url = request.getURI().getPath(); // 其中一些代码已省略,只保存了续约token的代码 String user = (String) redisUtil.get("token_" + tokenList.get(0)); if (!StringUtils.isEmpty(user)) { // 自动刷新缓存 tokenService.verifyToken(user); } } }
4.续约TokenService
/** * @author wangrui * @date 2024/1/19 * @description token **/ @Component @Slf4j public class TokenService { @Autowired private RedisUtil redisUtil; private static final long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; private static final long MILLIS_SECOND = 1000; private static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; private static final String TOKEN = "token_"; /** * 验证token * @param user user的json字符串,看具体存的啥就取啥,解析成所需要的user即可 */ public void verifyToken(String user) { UserEntity userEntity = JSONObject.parseObject(user).toJavaObject(UserEntity.class); long failureTime = userEntity.getFailureTime(); long currentTime = System.currentTimeMillis(); // 如果有效期小于20min则续约token if (failureTime - currentTime <= MILLIS_MINUTE_TEN) { refreshToken(userEntity); } } /** * 刷新token有效期 * @param userEntity u */ public void refreshToken(UserEntity userEntity) { userEntity.setLoginTime(System.currentTimeMillis()); userEntity.setFailureTime(userEntity.getLoginTime() + userEntity.getExpireTime() * MILLIS_MINUTE); // 刷新缓存 redisUtil.set(TOKEN + userEntity.getToken(), JSON.toJSONString(userEntity), userEntity.getExpireTime(), TimeUnit.MINUTES); } }
总结
清浅时光,心有明媚,处处温暖,情有阳光,时时灿烂。当内心充满祥和,在哪里都是一样欢喜自在;当内心充满智慧,一花一草尽显法身。若能放下心中的执着与挑剔,那么你相逢的一切,皆是美好。