Gateway(拦截器/路由)入门

Gateway(拦截器/路由)

Gateway 核心是一系列的过滤器 主要作用 过滤和路由
整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息
Geteway本身就是一个微服务,需要注册到Eureka中心
不管是来自于客户端(PC或移动端)的请求,还是服务内部调用,一切服务的请求都可以经过网关
实现鉴权 动态路由 服务的统一入口
在这里插入图片描述

1.使用Gateway

拦截请求中带 /users/ 的请求
拦截http://localhost:10086/users/2 — 跳转到------->http://localhost:8081
1.添加依赖 pom.xml

<dependencies>
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-gateway</artifactId>
          </dependency>

          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
          </dependency>
      </dependencies>


2.在启动类添加注解
@EnableDiscoveryClient //启用Gateway

@SpringBootApplication
@EnableDiscoveryClient   //启用Gateway
public class Demo04GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(Demo04GatewayApplication.class,args);
    }
}

3.配置.properties文件
拦截的请求类型spring.cloud.gateway.routes[0].predicates[0]=Path=/users/**

# service name
spring.application.name=demo04-gateway
#port
server.port=10086
# 找到Eureka的地址
eureka.client.service-url.defaultZone=http://localhost:8083/eureka,http://localhost:8084/eureka

# 路由id
spring.cloud.gateway.routes[0].id=demo04_gateway_1001
# provider的一个服务地址,就是拦截到之后跳到的地址
spring.cloud.gateway.routes[0].uri=http://localhost:8081
# 拦截的断言  要拦截带有/**的url
spring.cloud.gateway.routes[0].predicates[0]=Path=/users/**

4.测试

输入http://localhost:10086/users/1 转到http://localhost:8081/users/1拿到该provider的返回的结果

2.动态路由(面向服务的路由:之前把服务地址写死是不合理的,所以就要使用动态路由)

以(lb://lb://user-service为例)
原理:Gateway通过LoadBalanceClient把user-service通过Eureka解析成具体的host和端口,并进行负载均衡

使用在Eureka中注册的服务作为路由地址,而不是写死的地址
动态路由(面向服务的路由):在配置文件中指定路由路径类似于:
lb://lb://user-service

3.路由前缀处理 filter(对请求到网关的服务地址添加或者去除前缀)

请求地址与微服务的服务地址如果不一致的时候,可以通过配置路径过滤器实现路径前缀的添加和去除
添加
http://localhost:10086/3->http://localhost:10086/users/3

# 添加前缀
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
# 添加前缀 在客户端的请求地址上添加/users
 spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users

减少
http://localhost:10086/api/users/3->http://localhost:10086/users/3

#  减少前缀 在客户端的请求地址上减少前缀
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/users/**
# 1表示去除一前缀,2表示两个,一次类推
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1

4.过滤器(请求鉴权、异常处理、记录调用时长)

1.介绍
1.符合条件的请求放行,否则不放行

# 默认过滤器   spring.cloud.gateway.default-filters对所有的路由都生效
spring.cloud.gateway.default-filters[0]=AddResponseHeader=name,rose
spring.cloud.gateway.default-filters[1]=AddResponseHeader=age,34


在这里插入图片描述
2.过滤器分为两种
1)局部过滤器
只对当前路由起作用
1)spring.cloud.gateway.routes.filters

2)全局过滤器
作用在所有的路由上
1)spring.cloud.gateway.default-filters + 实现GatewayFilterFactory接口的过滤器
2) 实现GlobalFilter接口,不需要配置

2.自定义全局过滤器(判断url中是否有token参数,可以用于判断user对象是否为空)
1.实现接口
GlobalFilter接口 重写filter方法 拿到token,判断token是否为空,不为空则放行,如果token为null或者不存在则设置返回的状态码为:未授权
Order接口 重写getOrder()方法 系统调用该方法获得过滤器的优先级,返回的数字越小优先级越高
2.编写filter方法中的逻辑

package com.zx.demo04gateway.filter;


@Component
@Slf4j
public class MyParamGlobalFilter implements GlobalFilter , Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //拦截方法,拦截到请求后,自动执行
        log.info("filter 拦截方法,拦截到请求后,自动执行 ");
        //以后开发中,不会将 user对象存到session,只会在地址上带上token
        //根据token是否有空可以判断是否登录
        //http://localhost:8001/users/3?token=10001&pageSize=30
        String token =  exchange.getRequest().getQueryParams().getFirst("token");
        if(token == null || "".equals(token)){
            //未登录 跳转到登录页
            log.info("----跳到登录页面");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);//2 全部放行
    }

    @Override
    public int getOrder() {
        //3:系统调用该方法获得过滤器的优先级
        return 1; //数字越小,越优先
    }
}


3.自定义局部过滤器(请求鉴权、异常处理、记录调用时长)
1.添加局部过滤器配置

spring.cloud.gateway.routes[0].filters[1]=MyParam=name,address

2.继承AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> 抽象类
重写apply方法

3.编写静态内部类Config 要拦截的参数名

  @Data
    public static class Config{
        private String name;
        private String address;
    }

4.将config交给父类的构造方法

public MyParamGatewayFilterFactory() {
        super(Config.class);
    }

5.编写shortcutFieldOrder()方法,定义变量顺序

@Override
    public List<String> shortcutFieldOrder() {//定义变量的顺序
        List<String> order = new ArrayList<>();
        order.add("name");
        order.add("address");
        return order;
    }

6.编写重写的apply方法
因为返回的类型是一个接口 GatewayFilter,所以还要定义一个类(直接实例化接口,重写方法)来实现GatewayFilter接口,重写其中的 filter()方法

public GatewayFilter apply(Config config) {
        GatewayFilter gatewayFilter = new GatewayFilter(){

            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //http://localhost:10086/api/users/1?token=1&name=jack&address=zs
                String name = exchange.getRequest().getQueryParams().getFirst(config.name);
                String address = exchange.getRequest().getQueryParams().getFirst(config.address);
                log.info("filter ....name"+name);
                log.info("filter ....address"+address);
                log.info("filter ....拦截了请求");
                return chain.filter(exchange);//全部放行
            }
        };
        return gatewayFilter;//返回一个自己定义的过滤器
    }

7.全部的MyParamGatewayFilterFactory类

package com.zx.demo04gateway.filter;

@Component
@Slf4j
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {
    //5:将config交给父类的构造方法
    public MyParamGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        GatewayFilter gatewayFilter = new GatewayFilter(){

            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //http://localhost:10086/api/users/1?token=1&name=jack&address=zs
                String name = exchange.getRequest().getQueryParams().getFirst(config.name);
                String address = exchange.getRequest().getQueryParams().getFirst(config.address);
                log.info("filter ....name"+name);
                log.info("filter ....address"+address);
                log.info("filter ....拦截了请求");
                return chain.filter(exchange);//全部放行
            }
        };
        return gatewayFilter;//返回一个自己定义的过滤器
    }

    //3:定义顺序
    @Override
    public List<String> shortcutFieldOrder() {//定义变量的顺序
        List<String> order = new ArrayList<>();
        order.add("name");
        order.add("address");
        return order;
    }

    //2:定义config  name,address
     //http://localhost:10086/api/users/1?token=1&name=jack&address=zs
    @Data
    public static class Config{
        private String name;
        private String address;
    }
}


  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Gateway 是一个基于 Spring Cloud 微服务架构的网关框架,用于提供统一的访问入口并处理请求的转发和过滤。拦截器是 Spring Gateway 的一项重要功能,用于在请求到达网关之前或之后进行自定义的处理操作。 在网关进行验签时,可以通过拦截器来实现。拦截器可以拦截请求,并在请求到达网关之前进行验签操作,以确保请求的合法性和安全性。具体的实现步骤如下: 1. 创建一个拦截器类,该类需要实现 Spring Gateway 提供的 GatewayFilter 接口。在该类中,可以实现具体的验签逻辑,比如验证请求的签名是否正确,是否被篡改等。 2. 在拦截器类中重写 filter 方法,在该方法中编写具体的验签逻辑。可以从请求中获取相关的参数,比如请求的头部信息、路径、请求参数等,根据验签规则进行验签操作。 3. 配置拦截器,将其注册到 Spring Gateway 中。可以通过配置文件或者代码的方式将拦截器注册到网关中,使其生效。 4. 配置拦截器的顺序。如果有多个拦截器,在注册时需要指定拦截器的顺序,以确保验签拦截器在其他拦截器之前执行。 通过以上步骤,就可以实现对请求的拦截和验签操作。当请求到达网关时,拦截器会拦截请求,并根据预先定义的验签规则进行验签。如果验签不通过,可以根据具体需求进行相应的处理,比如返回错误信息或者拒绝请求。如果验签通过,则可将请求继续转发给相应的服务进行后续处理。 总结来说,Spring Gateway 拦截器可以用于实现请求的验签功能。通过编写自定义的拦截器类和配置其在网关中的注册顺序,可以灵活地控制请求的拦截和验签流程,提高系统的安全性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值