SpringBoot2中添加拦截器验证token值

前言

基础知识说明

  1. token是无状态的,帮助你验证用户是否具有查询api的权限,一般登录后即可生成。
  2. 拦截器下,解决swagger-ui的访问

拦截器

SpringBoot的拦截器,继承HandlerInterceptor即可,重写preHandle

说明:

  1. IAuthService 是我验证token的服务类,可自行编写
  2. R.failed() 是mybatis-plus包中
  3. filter不能直接注入spring容器里面的对象

代码如下:

@Component
@Slf4j
public class LoginTokenFilter extends HandlerInterceptorAdapter {

    @Autowired
    IAuthService authService;

    /**
     * 请求进去controller进行请求拦截
     *
     * @param request  请求
     * @param response 响应
     * @param handler  处理
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取头部header 信息
        String TOKEN = "x-access-token";
        String token = request.getHeader(TOKEN);
        //如果为空,表示未登录,禁止使用
        if (StringUtils.isEmpty(token)) {
            error(response, "您没有登录!");
            return false;
        } else {
            //不为空,但是redis 中不存在,请重新登录
            if (authService.checkLoginStatus(token)) {
                log.info("token 验证通过...");
                return true;
            } else {
                error(response, "登录过期,请重新登录!");
                return false;
            }
        }
    }

    /**
     * 错误信息
     *
     * @param response
     * @param msg
     */
    private void error(HttpServletResponse response, String msg) {
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "application/json");
        try {
            PrintWriter writer = response.getWriter();
            //将返回的错误提示压入流中
            writer.write(new ObjectMapper().writeValueAsString(R.failed(msg)));
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

配置拦截器

SpringBoot2中配置拦截器是继承WebMvcConfigurationSupport

说明:

  1. 解决了swagger-ui的访问
  2. 新增拦截器,配置不拦截路径
  3. 注意:WebMvcConfigurationSupport只能实现一个
  4. 需要配置 spring.main.allow-bean-definition-overriding=true
@Configuration
public class WebAppConfigurer extends WebMvcConfigurationSupport {

    @Bean
    LoginTokenFilter loginTokenFilter() {
        return new LoginTokenFilter();
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginTokenFilter())
                .addPathPatterns("/**")
                .excludePathPatterns("/sms/sendCaptcha", "/sms/checkCaptcha")
                .excludePathPatterns("/swagger-ui.html/**", "/v2/**", "/webjars/**", "/swagger-resources/**");
        super.addInterceptors(registry);
    }

    /**
     * 解决swagger-ui 无法访问
     * 两个方法都需要重写,只加任何一个都无法生效
     *
     * @param registry
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

问题:拦截器和跨域配置同时,但是不生效。在preHandle添加代码

//拦截器中配置跨域
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "3600");

swagger-ui添加header字段

默认的是没有header字段的,导致我们无法传输token值,我们需要狗构造出来。

在你的SwaggerConfig

@Bean
    public Docket createRestApi() {
        ParameterBuilder ticketPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();
        ticketPar.name("x-access-token").description("user token")
                .modelRef(new ModelRef("string")).parameterType("header")
                .required(false).build(); //header中的ticket参数非必填,传空也可以
        pars.add(ticketPar.build());    //根据每个方法名也知道当前方法在设置什么参数

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.warmapp.controller"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(pars);
    }

结果图:
SpringBoot2中添加拦截器验证token值_第1张图片
实际使用效果
SpringBoot2中添加拦截器验证token值_第2张图片
日志记录
在这里插入图片描述

以上可以满足单独的token验证,如果是网关,可以参考一下。

你可能感兴趣的:(Spring,Cloud)