java实现自定义免登录注解@LoginNotRequired,可加在controller或接口方法(需要登录也同理)
如何实现给接口或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("/**");
}
}
使用截图
本文来自博客园,作者:HumorChen99,转载请注明原文链接:https://www.cnblogs.com/HumorChen/p/18039514
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~