首页 > 其他分享 >Spring Boot自定义注释制作API接口拦截器进行TOKEN验证

Spring Boot自定义注释制作API接口拦截器进行TOKEN验证

时间:2023-02-09 16:14:56浏览次数:52  
标签:拦截器 自定义 Spring request public token userInfo response setHeader

一:自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ChackToken {
    boolean validate() default true;
}

二:自定义拦截器来实现 HandlerInterceptorAdapter

public class AuthorizationInterceptor  extends HandlerInterceptorAdapter {

    //redis操作各种方法
    @Autowired
    private RedisUtil redisUtil;
    public static final String USER_KEY = "userInfo";

    @Autowired
    private MiniWechatController miniWechatC;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //不是自定义ChackToken注释的跳过拦截
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        ChackToken annotation = handlerMethod.getMethodAnnotation(ChackToken.class);
        if(annotation == null || !annotation.validate()){
            return true;
        }
        /**
         * 项目在拦截器Interceptor中 注入RedisUtil,RedisUtil无法使用的问题(RedisUtil报null错误)
         * 原因:拦截器在SpringContext初始化之前就执行了,Bean初始化之前它就执行了,所以它肯定是无法获取SpringIOC容器中的内容的。
         * 需要加入以下代码代码即可
         */
        if (redisUtil == null) {
            WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
            redisUtil = wac.getBean(RedisUtil.class);
        }

        //设置跨域--开始
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
            setHeader(httpRequest,httpResponse);
            return true;
        }
        //设置跨域--结束


        //从header中获取token
        String token = request.getHeader("token");
        //如果header中不存在token,则从参数中获取token
        if(StringUtils.isBlank(token)){
            token = request.getParameter("token");
        }
        //token为空
        if(StringUtils.isBlank(token) || token == null || token.length() == 0){
            throw new RemoteException("缺少token,拒绝访问");
        }
        System.out.print("token:"+token);
        Object userInfo = null;
        userInfo = redisUtil.get(token);
//        //查询token信息
//        String openid = redisUtil.get(token).toString();
        if(userInfo == null ){
            throw new RemoteException("用户Token失效,请重新登录");
        }
        //设置openid到request里,后续根据openid,获取用户信息
        request.setAttribute(USER_KEY, userInfo);
        return true;
    }

    /**
     * 为response设置header,实现跨域
     */
    private void setHeader(HttpServletRequest request,HttpServletResponse response){
        //跨域的header设置
        response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", request.getMethod());
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
        //防止乱码,适用于传输JSON数据
        response.setHeader("Content-Type","application/json;charset=UTF-8");
    }
}

三:将自己定义的拦截器注入到Mvc中

这里有两种方式:

第一种是可以继承WebMvcConfigurationSupport,但是用这种我遇到一个问题就是,所有date-format格式被转成了时间戳!

第二种就是实现WebMvcConfigurer,这种不会出现这种情况,所以推荐第二种方式

@SpringBootConfiguration
public class SpringMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthorizationInterceptor());
    }
}

  

现在我们就可以在控制器中进行使用了

示例:

    @GetMapping("/text")
    @ChackToken
    public Result<ChUser> updateUser(HttpServletRequest request){
        System.out.print("userInfo:"+request.getAttribute("userInfo"));
        return Result.error("0");
    }

  

标签:拦截器,自定义,Spring,request,public,token,userInfo,response,setHeader
From: https://www.cnblogs.com/lhm166/p/17105595.html

相关文章

  • JAVA缓存规范 —— 虽迟但到的JCache API与天生不俗的Spring Cache
    大家好,又见面了。本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面。如果感兴趣,欢迎关注以获取后续更新。有......
  • 【Logback】自定义日志输出格式
    logback官方文档logback(二)springboot配置日志文件格式、logback-spring配置文件详解、logback为日志自定义颜色【史上最详细】logback(三)mybatis-plus结合logback将sql语......
  • SpringBoot 项目实战 | 瑞吉外卖 Day02
    该系列将记录一份完整的实战项目的完成过程,该篇属于第二天案例来自B站黑马程序员Java项目实战《瑞吉外卖》,请结合课程资料阅读以下内容该篇我们将完成以下内容:完善登陆......
  • SpringBoot 项目实战 | 瑞吉外卖 Day03
    该系列将记录一份完整的实战项目的完成过程,该篇属于第三天案例来自B站黑马程序员Java项目实战《瑞吉外卖》,请结合课程资料阅读以下内容该篇我们将完成以下内容:公共字段......
  • SpringBoot自动配置原理
    传统的Spring项目,需要我们对每个引入的组件进行手动配置。这需要开发者对组件有深入的了解,否则很容易遗漏某些细节。对于业务开发人员/公司来说,他们只需要知道如何使用组......
  • springboot开发日记(8)——插件
    1.lombok——简化JavaBean的开发普通的bean类需要写getter、setter、重写toString方法,较为麻烦。我们可以通过查找springboot的dependencies得知springboot的依赖里已经......
  • 使用Spring的JdbcTemplate进行CRUD
    packagecom.mo;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.util.List;importjavax.annotation.Resource;importorg.junit.Test;importorg.ju......
  • spring-security-oauth2-client与jdk版本不符合报错
    报错描述:java.lang.UnsupportedClassVersionError:org/springframework/security/oauth2/client/registration/ClientRegistrationRepositoryhasbeencompiledbyamo......
  • SpirngBoot+SpringSecurity+Jwt鉴权认证
    写在开头基础环境jdk1.8+maven3.8.5。为了简单起见,省略从表中查询数据,直接从dao返回用户权限数据。引入依赖<!--springboot--><dependency>......
  • 【Spring-boot-route(五)整合Swagger生成接口文档+(六)整合JApiDocs生成接口文档】
    目前,大多数公司都采用了前后端分离的开发模式,为了解决前后端人员的沟通问题,后端人员在开发接口的时候会选择使用swagger2来生成对应的接口文档,swagger2提供了强大的页面调试......