简介
在项目开发中我们有一些接口是不需要登录就可以调用的(即不需要校验token)。例如登录必须要放行,只有在登录后才能获取到token,如果不放行登录接口就陷入了死循环,永远都获取不到token。
在实际开发中都是使用拦截器来全局拦截所有请求校验token信息的,这时就需要开发一个注解@NoToken来对某些接口进行放行,使用@NoToken注解放行接口非常灵活好用,只需要在需要放心的接口上添加@NoToken注解,则调用此方法就不会校验token,也可以将@NoToken注解放在Controller类上,这就就不会校验此类下的所有接口。
代码实现
一、创建自定义注解@NoToken
@Inherited
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoToken {
}
二、修改token拦截器
在项目以后的拦截器中增加放行带有@NoToken注解的方法
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断是否放行【方法或者类含有@NoToken注解】
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 判断方法是否包含@NoToken
NoToken noToken = handlerMethod.getMethodAnnotation(NoToken.class);
if (noToken != null) {
return true;
}
// 判断方法所在的类是否包含@NoToken
noToken = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoToken.class);
if (noToken != null) {
return true;
}
// ---------- 以上为放行带有@NoToken注解方法代码-----------------
// ---------------------------------------------------------
// ---------- 以下为原有拦截器代码------------------------------
// 从请求头中获取token
String token = request.getHeader("token");
if (token == null || "".equals(token)) {
log.info("当前请求不包含token信息");
return false;
}
// 判断token是否过期,是否有效等信息
if (!checkToken(request)) {
log.info("token信息不符合规则");
return false;
}
return true;
}
private boolean checkToken(HttpServletRequest request) {
// todo 检查逻辑
if (!"token".equals(request.getHeader("token"))) {
return false;
}
return true;
}
}
测试方法
可以将@NoToken防止在方法或类上判断是否可以放行。防止在类上标识此类中的所有方法都不需要校验token信息。
@RestController
@RequestMapping("/test")
public class TestController {
@NoToken
@GetMapping("/test")
public String helloWorld() {
return "Hello World";
}
}