• hutool工具使用JWT.verify进行token验证,解析token,JWTUtil.parseToken


    前端部分:封装了axios进行请求拦截

    class Http {
      service: any;
      constructor(config: TOption) {
        //实例化请求配置
        this.service = axios.create(config);
        //请求拦截  Authorization自定义名字
        this.service.interceptors.request.use(
          (config: AxiosRequestConfig) => {
            loading = ElLoading.service({ fullscreen: true,text:'加载中...' });
            console.log(token.value);
            if (token.value) {
              (config.headers as AxiosRequestHeaders).Authorization = token.value;
            }
            return config;
          },
          (error: any) => {
            loading.close();
            return Promise.reject(error);
          }
        );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    完整代码:

    import axios, {
      AxiosRequestConfig,
      AxiosRequestHeaders,
      AxiosResponse,
    } from "axios";
    import { ElMessage, ElLoading } from "element-plus";
    import { storeToRefs } from "pinia";
    import appStore from "@/store/appStore";
    let {  token } = storeToRefs(appStore());
    
    const state = {
      ok: 0,//请求成功状态码
      401:"ERR_BAD_REQUEST"
    };
    
    //返回数据规则
    interface IResponseData<T> {
      status: number;
      message?: string;
      data: T;
      code: string;
    }
    
    //请求默认配置规则
    type TOption = {
      baseURL: string;
      timeout: number;
    };
    
    //默认配置
    const config = {
      baseURL: "",
      timeout: 30 * 1000,
      withCredentials: true,
    };
    
    
    let loading:any = null;
    
    class Http {
      service: any;
      constructor(config: TOption) {
        //实例化请求配置
        this.service = axios.create(config);
    
        //请求拦截  Authorization自定义名字
        this.service.interceptors.request.use(
          (config: AxiosRequestConfig) => {
            loading = ElLoading.service({ fullscreen: true,text:'加载中...' });
            console.log(token.value);
            if (token.value) {
              (config.headers as AxiosRequestHeaders).Authorization = token.value;
            }
            return config;
          },
          (error: any) => {
            loading.close();
            return Promise.reject(error);
          }
        );
    
        //响应拦截
        this.service.interceptors.response.use(
          (response: AxiosResponse) => {
            loading.close();
    
            const data = response.data;
          
            const { code } = data;
      
            if (code == undefined) {
              //如果没有返回状态码,直接返回数据,针对于返回数据为blob类型    
              return response;
            } else if (code !== 0) {
              ElMessage.error(data.message);
              return Promise.reject(data);
            }
            // code == 0 的时候,提取我们只关注的Api数据data
            return response.data.data;
          },
          (error: any) => {
            loading.close();
         
            if(error.code==state[401]){
              ElMessage.error("请求失败:"+error.message);
    
              setTimeout(() => {
                localStorage.removeItem('com.beiyou')
                window.location.href = '/#/login'
              },1000);
            }
            return Promise.reject(error);
          }
        );
      }
    
      get<T>(url: string, params?: object, data = {}): Promise<IResponseData<T>> {
        return this.service.get(url, { params, ...data });
      }
    
      post<T>(url: string, params?: object, data = {}): Promise<IResponseData<T>> {
        return this.service.post(url, params, data);
      }
    
      put<T>(url: string, params?: object, data = {}): Promise<IResponseData<T>> {
        return this.service.put(url, params, data);
      }
    
      delete<T>(
        url: string,
        params?: object,
        data = {}
      ): Promise<IResponseData<T>> {
        return this.service.delete(url, { params, ...data });
      }
    }
    
    export default new Http(config);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118

    后端进行验证
    首先自定义注解排除token校验注解类
    为不需要校验 token 的方法定义注解
    @Documented //标记注解
    @Target(ElementType.METHOD) //指定作用在方法上 对方法拦截
    @Retention(RetentionPolicy.RUNTIME) //作用域 在运行时有效

    import java.lang.annotation.*;
    
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface NoAuthorization {
        String value() default "";
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    自定义的token秘钥
    application.properties

    token.key = great123
    
    • 1

    编写拦截器token验证的拦截器
    1.实现HandlerInterceptor接口重写preHandle方法
    2.获取正在运行的方法上面,是否有@NoAuthorization注解,如果有就结束执行,不拦截,不校验token
    3.获取前端传来的token,如果有就进行JWTUtil.verify验证,没有就直接抛出401交给前端处理
    TokenInterceptor.java

    import cn.hutool.core.util.StrUtil;
    import cn.hutool.jwt.JWTUtil;
    import com.beimao.annotation.NoAuthorization;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @Slf4j
    public class TokenInterceptor implements HandlerInterceptor {
    
        //由于注册器那边是new的新对象,所以拦截器这边不能注册到IOC容器里面
        //这边采用构造方法的形式传参给注册器,由注册器注入到IOC容器里面
        private String tokenKey;
    
        public TokenInterceptor(String tokenKey) {
            this.tokenKey = tokenKey;
        }
    
        @Override
        public boolean preHandle(HttpServletRequest request,
                                 HttpServletResponse response,
                                 Object handler) throws Exception {
    
            if (handler instanceof HandlerMethod) {
                //handler是object类型不能直接调用,如果不强转可以用反射handler.getClass().getMethod()
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                //判断有没有注解
                NoAuthorization noAuthorization = handlerMethod.getMethod().getAnnotation(NoAuthorization.class);
                if (noAuthorization != null) {
                    //如果有该注解,证明该方法不需要token验证;
                    return true;
                }
               }
    
            //获取token 前端起的名字Authorization
            String token = request.getHeader("Authorization");
    
            //如果token不为空,进行token验证
            if (StrUtil.isNotEmpty(token)) {
                // 证token   verify(toen,秘钥.getBytes) hu-tool工具类  返回布尔类型  验证内容是否相当和是否过期
                boolean pass = JWTUtil.verify(token, tokenKey.getBytes());
    
                if (pass == false) {
                    //验证失败,返回401
                    response.setStatus(401);
                    return false;
                } else {
    
                    return true;
                }
            }
    
            //没有token,直接返回401
            response.setStatus(401);
            return false;
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    最后进行token拦截器注册

    import com.beimao.interceptor.TokenInterceptor;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Value("${token.key}")
        private String tokenKey;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            TokenInterceptor loginInterceptor = new TokenInterceptor(tokenKey);
            registry.addInterceptor(loginInterceptor)
                    .addPathPatterns("/api/**"); //拦截请求的url前缀
            //.excludePathPatterns("/css/**","/images/**","/js/**");// 放行
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    毕业4年,薪资25k,这一刻,我决定从字节离职了···
    MATLAB | 老版本也能用,默认设置让简单的代码画出炫酷的图像
    Promise 及其基于 Typescript 的实现
    Davinci Developer Classic SWC新建port并连接非complete port方式
    Golang链路追踪:实现高效可靠的分布式系统监控
    高级架构师_Docker_第2章_ Docker核心原理_ 第6节Docker部署微服项目
    Linux上Qt和Opencv人脸识别项目学习路线(嵌入式/C++)
    webservice接口调用
    MySQL占用内存过大解决方案
    9、求二叉搜索树第k小值
  • 原文地址:https://blog.csdn.net/weixin_44728473/article/details/125546979