如何实现给接口或Controller加上我自己的注解就能让他必须登录或者不需要登录就能访问呢?
@RequestMapping("/test2") @LoginNotRequired public String test2() { return "test2"; }
@RestController @RequestMapping("user") @LoginNotRequired public class UserController { }
/** * 该接口无需登录 * 加该注解不影响对已登录用户的读取和@UserId、@LoginedUser注入 * * @author : humorchen * @date 2021/12/5 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface LoginNotRequired { }
我们实现可能有所不同,但是道理是一样的,就是定义一个intercepto( implements HandlerInterceptor)拦截掉所有请求,在请求被处理器执行之前(preHandle)就去执行我们的鉴权操作
/** * 用户登录拦截器 * * @author :humorchen * @date 2022/1/1 21:53 */ @Component @Slf4j public class UserLoginInterceptor implements HandlerInterceptor { @Autowired private IUserAuthUtil userAuthUtil; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean loginNotRequired = false; if (handler instanceof HandlerMethod) { //转换对象 HandlerMethod handlerMethod = (HandlerMethod) handler; //controller类 Class controllerClass = handlerMethod.getBean().getClass(); //类上有没有免登录注解 boolean controllerHasLoginNotRequired = controllerClass.isAnnotationPresent(LoginNotRequired.class); if (controllerHasLoginNotRequired) { loginNotRequired = true; } //方法上有没有免登录注解 boolean methodHasLoginNotRequired = handlerMethod.hasMethodAnnotation(LoginNotRequired.class); if (methodHasLoginNotRequired) { loginNotRequired = true; } //检验登录的token String token = request.getHeader(IUserAuthUtil.HEADER_NAME); if (!StringUtils.isEmpty(token)) { //有token //token格式不对 BusinessAssert.isTrue(userAuthUtil.checkTokenFormat(token), CommonErrorEnums.LOGIN_INVALID); //检查token Long userId = userAuthUtil.checkToken(token); //没登录(免登录) BusinessAssert.isTrue(loginNotRequired || !(userId == IUserAuthUtil.NOT_LOGIN), CommonErrorEnums.NEED_LOGIN); //登录失效 BusinessAssert.isTrue(!(userId == IUserAuthUtil.LOGIN_INVALID), CommonErrorEnums.LOGIN_INVALID); if (userId > 0) { //获取用户信息 User user = userAuthUtil.getUserFromRedis(userId); //设置到request attribute里 request.setAttribute(IUserAuthUtil.LOGINED_USER, user); } } else { //没有token又没有免登录就打回 BusinessAssert.isTrue(loginNotRequired, CommonErrorEnums.NEED_LOGIN); } } return true; } }
/** * spring mvc web 配置 * * @author :humorchen * @date 2022/1/1 22:14 */ @Configuration public class WebMvcConfiguration implements WebMvcConfigurer { @Autowired private UserLoginInterceptor userLoginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { //拦截所有请求做登录检查 registry.addInterceptor(userLoginInterceptor).addPathPatterns("/**"); } }