这是没有优化之前的业务逻辑
这是优化后的
未优化:用户在登录后只有在访问需要拦截的路径token才会刷新访问未拦截的路径,token不会刷新,会导致token失效
优化:为了能够一直触发刷新token有效期的动作,我们需要添加一个拦截器,第一个拦截器负责token刷新拦截一切路径,只要用户登录后只要一直访问页面,token就会一致刷新,第二个拦截器则负责验证用户是否登录。
负责刷新token的拦截器
public class RefreshTokenInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1.获取请求头中的token
String token = request.getHeader("authorization");
if (StrUtil.isBlank(token)) {
return true;
}
// 2.基于TOKEN获取redis中的用户
String key = LOGIN_USER_KEY + token;
// System.out.println(stringRedisTemplate.getClass());
Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);
// 3.判断用户是否存在
if (userMap.isEmpty()) {
return true;
}
// 5.将查询到的hash数据转为UserDTO
UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
// 6.存在,保存用户信息到 ThreadLocal
UserHolder.saveUser(userDTO);
// 7.刷新token有效期
stringRedisTemplate.expire(key, LOGIN_USER_TTL, TimeUnit.MINUTES);
// 8.放行
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 移除用户
UserHolder.removeUser();
}
}
负责验证是否登录的拦截器
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断是否需要拦截(Threadlocal中是否有用户)
if(UserHolder.getUser() == null){
//没有需要拦截
response.setStatus(401);
return false;
}
//有用户
return true;
}
}
注册拦截器
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断是否需要拦截(Threadlocal中是否有用户)
if(UserHolder.getUser() == null){
//没有需要拦截
response.setStatus(401);
return false;
}
//有用户
return true;
}
}