18-微服务网关-Zuul过滤器落地

Zuul网关过滤器

Zuul它包含了两个核心功能:对请求的路由和过滤。

其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础;而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。其实,路由功能在真正运行时,它的路由映射和请求转发同样也由几个不同的过滤器完成的。所以,过滤器可以说是Zuul实现API网关功能最为核心的部件,每一个进入Zuul的HTTP请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。

Zuul 中的过滤器跟我们之前使用的 javax.servlet.Filter 不一样,javax.servlet.Filter 只有一种类型,可以通过配置 urlPatterns 来拦截对应的请求。

Zuul 中的过滤器总共有 4 种类型,且每种类型都有对应的使用场景。

过滤的结构图

image-20210105111420628

PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。

ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。

POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP

Header、收集统计信息和指标、将响应从微服务发送给客户端等。

ERROR:在其他阶段发生错误时执行该过滤器

PRE过滤器的案例

Pre过滤器的适用场景:身份认证,脱敏处理,编码集的统一设置……

过滤器的方法讲解
/**
 * 身份认证过滤器
 */
@Component
public class IdentityAuthFilter extends ZuulFilter {
    /**
     * 用来指定过滤器的类型
     * pre route post error
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * 过滤器的顺序
     * @return 返回的Int越小,越先执行
     * 每个过滤器,默认都有一个中间值5
     */
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    /**
     * 用来判断哪些路径,是需要做过滤处理的
     * @return true 需要做过滤(就是需要执行run())  false 不需要做过滤(就是不需要执行run())
     */
    @Override
    public boolean shouldFilter() {
        return false;
    }

    /**
     * 具体的过滤器规则
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        return null;
    }
}
热部署配置
  1. 在pom.xml中,添加热部署的依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
    
  2. 在application.yml,开启热部署

    spring:
      application:
        name: micro-zuul-server
      devtools:
        restart:
          enabled: true
          additional-paths: /src/main/java
          exclude: WEB-INF/**
    
  3. 勾选IDEA热部署规则

image-20210105114644469

身份认证过滤器
导入fastjson的依赖,导入commons微服务的依赖
        <!--导入公共模块-->
        <dependency>
            <groupId>com.woniuxy</groupId>
            <artifactId>micro-common-server</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.73</version>
        </dependency>
在commons中,创建res目录,并导入响应实体类
/**
 * 响应实体对象
 */
@Data
@Builder
public class ResponseMsg implements Serializable {

    /**
     * 在使用@Buidler后,如果要自定义构造器,需要使用该注解才生效
     */
    @Tolerate
    public ResponseMsg(){

    }

    private Integer code;
    private String msg;
    /**
     * 返回的消息
     */
    private Object data;

}

基础认证(垃圾的方案)

垃圾方案:模拟Cookie +Session 向后端通过Header传递JSessionId数据

/**
 * 身份认证过滤器
 */
@Component
public class IdentityAuthFilter extends ZuulFilter {
    /**
     * 用来指定过滤器的类型
     * pre route post error
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * 过滤器的顺序
     * @return 返回的Int越小,越先执行
     * 每个过滤器,默认都有一个中间值5
     */
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    /**
     * 用来判断哪些路径,是需要做过滤处理的
     * @return true 需要做过滤(就是需要执行run())  false 不需要做过滤(就是不需要执行run())
     */
    @Override
    public boolean shouldFilter() {
        //请求上下文对象
        RequestContext requestContext = RequestContext.getCurrentContext();
        //获得请求对象
        HttpServletRequest request = requestContext.getRequest();
        //获得请求路径
        String path = request.getRequestURI();// 某个微服务/请求路径
//        request.getRequestURL();// http://ip:port/某个微服务/请求路径
        System.out.println("path------" + path);

        /*注册方法,登录方法 这些是不需要执行过滤处理的*/
        if(path.equals("/micro-permission-server/admin/login")
                || path.equals("/micro-permission-server/admin/register")){
            return false;
        }

        return true;
    }

    /**
     * 具体的过滤器规则
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        System.out.println("执行过滤方法");
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //从Http Header中,判断是否有JsessionId的存在
        String val = request.getHeader("JsessionId");
        if(StringUtils.hasLength(val)){
            //有长度,暂时默认成功
            System.out.println("进入到微服务");


        }else{//如果没有长度,或者为NULL,设置响应失败(401)
            //不进入到下一步(route过滤器)
            requestContext.setSendZuulResponse(false);

            //设置响应数据
            HttpServletResponse response = requestContext.getResponse();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            requestContext.setResponse(response);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            requestContext.setResponseBody(JSONObject.toJSONString
                    (ResponseMsg.builder().code(10001).msg("未进行身份认证").build()));
        }

        return null;
    }
}

esponseStatusCode(HttpStatus.UNAUTHORIZED.value());
requestContext.setResponseBody(JSONObject.toJSONString
(ResponseMsg.builder().code(10001).msg(“未进行身份认证”).build()));
}

    return null;
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值