java接口调用过滤token

业务背景

处于对于安全需求,现需要将所有开放式接口(模板下载接口除外)转换为请求头Bear认证接口,因此需要在接口调用前加拦截器或者过滤器。

拦截器和过滤器

执行顺序:Request(请求)–>Filter(过滤器)–>Servlet(服务程序)–>Interceptor(拦截器)–>Controller(控制层)
可以理解为:

  • 过滤器是在请求进入Servlet之前,将不符合要求的请求过滤掉
  • 拦截器是在请求进入Servlet之后,将不符合的请求拦截,只返回部分预期的请求

过滤器和拦截器实际上基本相同,很多时候,过滤器与拦截器主要区别在于执行时机,根据不同业务的拦截时机来选择使用过滤器还是拦截器。

自定义过滤器实现

此篇文章使用过滤器进行token拦截过滤
自定义过滤器(代码):

/***************
 * 接口调用验证过滤器
 * @author zhou
 * @time 2024-01-02
 */
@Component
@Slf4j
public class TokenAuthorFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setContentType("text/plain;charset=UTF-8");

        String method = httpServletRequest.getMethod();
        //放行 options(嗅探) 请求
        if ("OPTIONS".equals(method)) {
            chain.doFilter(request, response);
            return; //跳过该嗅探请求
        }
        /*
            在SpringBoot中,ServletRequest和HttpServletRequest都是Java Web开发中的重要接口。
        ServletRequest是Java Web开发中定义的基本请求接口,它提供了获取请求参数、获取请求数据、获取客户端请求信息等方法。
        HttpServletRequest是ServletRequest的子类,它添加了一些处理HTTP协议相关的方法,如获取HTTP请求头、获取请求方式、获取会话信息等。
        */
        //1.获取请求url
        String url = httpServletRequest.getRequestURL().toString();
        //放行 模板下载请求
        if (url.contains("template") || url.contains("Template")) {
            chain.doFilter(request, response);
            return; //跳过该请求
        }
        if (url.contains("public-service")) {  // 拦截包含开放式接口请求路径的请求
            String bearer = httpServletRequest.getHeader("Bear");
            if (StringUtils.isEmpty(bearer)) {
                log.info("token不存在,返回未登录的信息");
                //因为没有在controller层,无法使用@RestController注解,需要自己将返回的数据转为JSON格式;
                String string = JSON.toJSONString(R.failed("登录信息不存在"));
                 /*
                 	getWriter() 是 httpServletResponse 接口的一个方法,它返回一个 PrintWriter 对象,用于将数据写入到响应输出流中。
                	write(string) 是 PrintWriter 对象的一个方法,用于将指定的字符串写入到响应输出流中。
                */
                httpServletResponse.getWriter().write(string); // 写入返回内容
                return;
            }
            // 使用redis进行token验证
            RedisUtils redisUtils = getBean(RedisUtils.class, httpServletRequest);
            String objects = (String) redisUtils.get("{pb" + bearer + "}"); // 自定义验证规则,与登录规则匹配
            if (StringUtils.isNotEmpty(objects)) {
                chain.doFilter(request, response);
            } else {
                String string = JSON.toJSONString(R.failed("验证信息不存在"));
                httpServletResponse.getWriter().write(string);
            }
        } else {
            chain.doFilter(request, response);
        }

    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    /**
     * 由于在过滤器中无法直接通过Autowired获取Bean,Bean还未自动注入,因此需要通过spring上下文来获取IOC管理的实体类
     * 此处主要是用于  RedisUserUtils
     *
     * @param clazz
     * @param request
     * @param <T>
     * @return
     */
    public <T> T getBean(Class<T> clazz, HttpServletRequest request) {
        WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
        return applicationContext.getBean(clazz);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值