往往在一些后台管理需求中,后台请求接口一般都需要token参数才能访问,下面介绍以下自定义@NeedToken注解使用切面aop技术决定请求接口是否需要token参数
目的
接口若有@NeedToken注解,若请求不携带token,则会抛出无token异常
接口若无该注解,不携带token,可正常请求该接口
思路
1.首先定义一个@NeedToken注解,作用于方法上
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NeedToken {
}
2.定义切面拦截
继承HandlerInterceptorAdapter类,重写preHandle方法,尝试分别从请求头,请求参数,cookie中获取token,若最后token为null,且需要token,则抛出无token,无权访问异常
@Component
public class LoginTokenInterceptor extends HandlerInterceptorAdapter {
private static final String TOKEN_KEY = "token";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断访问的方法上是否有@needToken注解
HandlerMethod handlerMethod = (HandlerMethod) handler;
boolean needToken = handlerMethod.hasMethodAnnotation(NeedToken.class);
// 尝试从请求头从获取token
String token = request.getHeader(TOKEN_KEY);
if (StringUtils.isEmpty(token)) {
// 尝试从请求参数中获取token
token = request.getParameter(token);
}
if (StringUtils.isEmpty(token)) {
// 尝试从cookie获取token
if (request.getCookies() != null && request.getCookies().length != 0) {
for (Cookie cookie : request.getCookies()) {
if (TOKEN_KEY.equals(cookie.getName())) {
token = cookie.getValue();
}
}
}
}
// 若token为空,且需要token
if (StringUtils.isEmpty(token)) {
if (needToken) {
throw new RuntimeException("无token,无权访问");
}
}
return super.preHandle(request, response, handler);
}
}
3.添加拦截器,将该拦截点放入拦截器
@Configuration
public class SpringMvcConfig extends WebMvcConfigurerAdapter {
@Resource
private LoginTokenInterceptor tokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册Token拦截器
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**");
super.addInterceptors(registry);
}
}
4.测试用例
@RestController
public class TestController {
/**
* 测试,需要token
*/
@GetMapping("/test")
@NeedToken
public String test() {
return "访问成功";
}
/**
* 测试,无token
*/
@GetMapping("/test1")
public String test1() {
return "访问成功";
}
}
5.测试结果
访问test接口,并不携带token,则出现
携带token后
总结
AOP在项目开发中真香,大家可自行测试