Redis企业项目实战--登录校验拦截器

2024-03-01 12:35:42 浏览数 (20)

拦截器

在这里插入图片描述在这里插入图片描述

拦截器的作用在于将重复的登录校验功能安装在拦截器上(某些请求需要要求用户等登录才能启用)但不可能在每一个业务模块都写校验的代码,于是拦截器的作用就在于拦截请求 去检查用户的状态 是否处于在线 若是在线就刷新token的有效期 token存在Redis中

细节实现就不说了 实现部分的代码

这是一号拦截器 只需要检查ThreadLocal中是否有用户(有说明登录了,因为登录校验操作中会把用户信息存在ThreadLocal)

代码语言:text复制
Java
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1.判断是否需要拦截(ThreadLocal中是否有用户)
if (UserHolder.getUser() == null) {
response.setStatus(401);
return false;
}

return true;
}
}

二号拦截器

这里我们注入了Redis因为要用Redis来存用户信息

代码语言:javascript复制
public class RefreshTokeninterceptor implements HandlerInterceptor {

    //而MvcConfig中使用了 LoginInterceptor 所以我们要去到MvcConfig进行注入
    private StringRedisTemplate stringRedisTemplate;
    //因为这个类不是spring boot构建的,而是手动创建的类,所以依赖注入不能用注解来注入,要我们手动使用构造函数来注入这个依赖
    public RefreshTokeninterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求头中的token  在前端代码中详见authorization
        String token = response.getHeader("authorization");
        if(StrUtil.isBlankIfStr(token)){{//判断是否为空
            return  true;
        }
        // 基于token获取Redis用户
        String Token = RedisConstants.LOGIN_USER_KEY   token;
        Map<Object,Object> UserMap = stringRedisTemplate.opsForHash().entries(Token);
        //判断用户是否存在
        if(UserMap.isEmpty()){
            return  true;
        }
        // 将查询到的hash数据转化为userDTO对象
        //fillBeanWithMap是用UserMap来填充 UserDTO这个Bean,最后一个参数是你是否忽略转换过程中的错误
        UserDTO user = BeanUtil.fillBeanWithMap(UserMap, new UserDTO(), false);
        //存在 保存用户信息到TheadLocal
        UserHolder.saveUser(user);
        //刷新token有效期
        stringRedisTemplate.expire(Token,RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);
        //放行
        response.setStatus(200);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //移除用户
        UserHolder.removeUser();
    }
}

最后是配置拦截器

代码语言:javascript复制
@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    //添加拦截器  InterceptorRegistry registry 拦截器的注册器  excludePathPatterns排除不需要的拦截的路径
    // 只要跟登录无关就不需要拦截  拦截器的作用只是校验登录状态
    public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor())
                    .excludePathPatterns(
                    "/user/login",
                    "/user/code",
                    "/blog/hot",
                    "/shop/**",
                    "/shop-type/**",
                    "/voucher/**"
            ).order(1);
        //order是设置先后
        //刷新token的拦截器
        registry.addInterceptor(new RefreshTokeninterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);
    }

}

0 人点赞