在系统中,在 token 的有效期内,可以登录使用,并且要求如果一直使用系统,一直保持登录状态,而不是 token 过期就直接退出系统了,所以需要在操作系统时保持对 token 有效期的续期。
本文是以 gateway 网关过滤器功能实现。
提示:以下是本篇文章正文内容,下面案例可供参考
private Integer expireTime; // 登录超时时间,单位min,此为数据库存的,用户可以自由设置过期时间(按需操作)
private Long loginTime; // 登录时间
private Long failureTime; // 过期时间
private String token; // 用户唯一标识
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());
}
}
@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);
}
}
}
/**
* @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);
}
}
清浅时光,心有明媚,处处温暖,情有阳光,时时灿烂。当内心充满祥和,在哪里都是一样欢喜自在;当内心充满智慧,一花一草尽显法身。若能放下心中的执着与挑剔,那么你相逢的一切,皆是美好。