实现token统一其主要目的是,每次客户端发起请求的时候,其它业务功能需要权限才能进行下去,而又不想每次都去查询数据库校验,所以可以通过ThreadLocal这个类的api来实现线程与对象绑定来实现token处理的统一。
实现步骤
1.配置拦截器配置类(实现WebMvcConfigurer重写addInterceptors方法)
2.定义拦截器类HandlerInterceptor重写preHandler方法)
3.自定义一个注解,标识不需要token的方法不进行拦截,需要token的方法就进行拦截
4.自定义ThreadLocal类,在里面创建ThreadLocal的对象,用final关键字修饰
下面是代码演示,可以借鉴,根据自己需求去改。
第一步代码
/**
* 拦截器的配置类,
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private TokenInterceptor tokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(this.tokenInterceptor).addPathPatterns("/**");
}
}
第二步:
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
NoAuthorization noAnnotation = handlerMethod.getMethod().getAnnotation(NoAuthorization.class);
if (noAnnotation != null) {
// 如果该方法被标记为无需验证token,直接返回即可
return true;
}
}
String token = request.getHeader("Authorization");
if (StringUtils.isNotEmpty(token)) {
User user = this.userService.queryUserByToken(token);
if (null != user) {
UserThreadLocal.set(user); //将当前对象,存储到当前的线程中
return true;
}
}
//请求头中如不存在Authorization直接返回false
response.setStatus(401); //无权限访问
return false;
}
第三步
@Target(ElementType.METHOD) //方法注解
@Retention(RetentionPolicy.RUNTIME)
@Documented //标记注解
public @interface NoAuthorization {
}
第四步
public class UserThreadLocal {
//在这里把LOCAL变成静态常量,在后面的其它功能中就能直接通过它获取对象
private static final ThreadLocal<User> LOCAL = new ThreadLocal<User>();
private UserThreadLocal() {
}
public static void set(User user) {
LOCAL.set(user);
}
public static User get() {
return LOCAL.get();
}
}
其主要代码的实现是根据ThreadLocal这个类的api的进行实现的,有需要的可以看下一篇文章。