🥩 校验是否登录
用户发送请求不止一次,所以说登录验证也不止进行一次,于是可以使用拦截器完成验证,拦截器的使用可分为两步:
创建拦截器
/** * @author : mereign * @date : 2022/5/5 - 10:31 * @desc : 拦截器,实现请求拦截,判断登录信息 */ @Component public class LoginInterceptor implements HandlerInterceptor { @Autowired private StringRedisTemplate stringRedisTemplate; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取请求头中的token信息 String token = request.getHeader("authorization"); if (StrUtil.isBlank(token)) { // token为空,返回401未授权状态码,拦截 response.setStatus(401); return false; } // 根据token获取redis中的用户value Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(RedisConstants.LOGIN_USER_KEY + token); HttpSession session = request.getSession(); // 判断用户是否存在 if (userMap.isEmpty()) { // 用户不存在,返回401未授权状态码,拦截 response.setStatus(401); return false; } // 用户存在,将hash数据转换为userDTO,存信息到ThreadLocal UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false); UserHolder.saveUser(userDTO); // 刷新token有效期,放行 stringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY + token, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { UserHolder.removeUser(); } }
注册拦截器
/** * @author : mereign * @date : 2022/5/5 - 10:43 * @desc : */ @Configuration public class MvcConfig implements WebMvcConfigurer { @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .excludePathPatterns( "/shop/**", "/shop-type/**", "/voucher/**", "/upload/**", "/blog/hot", "/user/code", "/user/login" ); } }
缓存用户的信息到ThreadLocal中的工具方法
public class UserHolder { private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>(); public static void saveUser(UserDTO user){ tl.set(user); } public static UserDTO getUser(){ return tl.get(); } public static void removeUser(){ tl.remove(); } }
UserController定义与前端交互
@GetMapping("/me") public Result me(){ // 获取当前登录的用户并返回 UserDTO user = UserHolder.getUser(); return Result.ok(user); }