前言:

在我们之前所用的Nacos和Feign以及Eureka,这些组件都是用与系统内部之间进行互相访问的,但是当用户访问系统时,我们没有采取任何措施,举个例子:系统管理员可以访问哪些接口并具备哪些操作权限,普通用户又可以访问哪些接口以及访问权限。这些我们都是没有做限制的,因此,我们需要一个组件来对访问的请求进行一些处理,这就可以使用我们接下来要讲的GateWay了。

一、网关(GateWay)的作用

1、身份认证和权限校验

对用户的身份信息以及操作权限进行校验。

2、服务路由、负载均衡

将用户发送的请求路由到某个微服务,如果该微服务存在多个实例,路由时就会采用负载均衡。

3、请求限流

当请求过载时,就会限制请求的路由量。

二、GateWay搭建

1、导入依赖

<!--gateway网关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!-- nacos客户端依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

 2、编写路由配置及Nacos地址

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:80
    gateway:
      routes: #配置路由规则
        - id: user-service #路由标识,必须唯一
          uri: lb://userservice #路由的目标地址 lb表示loadBalance(负载均衡)
          predicates: #路由断言,判断请求是否符合规则
            - Path=/user/** #判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**

 3、启动微服务,查看Nacos控制台微服务实例详细信息

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring cloud

 我们启动了三个userService实例和一个orderService实例。

4、通过网关访问微服务系统

4.1、浏览器输入地址:

http://localhost:10010/user/1
http://localhost:10010/order/101

4.2、查看页面响应:

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring cloud_02

 

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring_03

 4.3、查看系统后台控制台信息

我们分别输入用户id为1、2、3,访问三次,查看控制台信息得知,此时gateway的负载均衡采用的是随机规则,即将请求随机发送给某服务的某个实例。

4.4、流程图

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_04

 4.5、总结

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring_05

三、路由断言工厂

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_gateway_06

 1、Spring当中为我们提供的断言规则有哪些

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring_07

 2、案例演示(Before和After)

2.1、order-service断言配置

- id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
            - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

 2.2、user-service断言配置

- id: user-service #路由标识,必须唯一
          uri: lb://userservice #路由的目标地址
          predicates: #路由断言,判断请求是否符合规则
            - Path=/user/** #判断路径是否是以/user开头,如果是则符合
            - After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

 2.3、浏览器测试

系统测试时间:

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_08

(1)order-service

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_09

(2)user-service

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_10

(3)结论

断言规则After表示,请求访问时间是否在此时间之后,如何是,则允许请求路由到微服务实例当中进行处理,否则404.

断言规则Before表示,请求访问时间是否在此时间之前,如果是,则允许请求路由到微服务实例当中进行处理,否则404.

3、总结

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_11

四、路由过滤器(GatewayFilter)

1、路由过滤器的作用

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_微服务_12

 用户发送的请求,首先会抵达网关,网关并不会直接将请求路由到对应的微服务当中去执行,而是将请求传递给过滤器,由过滤器对请求做出一系列处理之后才转发到微服务当中,同理,微服务处理完请求后也不会直接将响应传递到路由上,也是经过一系列过滤器之后才抵达路由,由路由对用户的访问进行响应。

 2、如何实现

案例一(局部——添加请求头信息):

(userService)网关配置:

- id: user-service #路由标识,必须唯一 uri: lb://userservice #路由的目标地址 predicates: #路由断言,判断请求是否符合规则 - Path=/user/** #判断路径是否是以/user开头,如果是则符合 filters: - AddRequestHeader=Truth,ZYP IS SO aowsome!

userController代码调整:

@GetMapping("/{id}") public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "Truth",required = false) String truth) { System.out.println(truth + ">>>>>>>>>>>>>>>>"); return userService.queryById(id); }

效果验证:

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_13

 案例二(全局——添加请求头信息):

全局网关配置:

gateway: routes: #配置路由规则 - id: user-service #路由标识,必须唯一 uri: lb://userservice #路由的目标地址 predicates: #路由断言,判断请求是否符合规则 - Path=/user/** #判断路径是否是以/user开头,如果是则符合 - id: order-service uri: lb://orderservice predicates: - Path=/order/** default-filters: - AddRequestHeader=Truth,My mother holds a special place in my heart.

效果验证:

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring cloud_14

五、全局过滤器(GlobalFilter)

全局过滤器是对路由过滤器功能的一种补充和扩展。

@Component
@Order(0)//过滤器的顺序,越小优先级越高
public class AuthorizeFilter implements GlobalFilter{
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String,String> params = request.getQueryParams();
        //2.获取参数中的authorization参数
        String value = params.getFirst("authorization");
        //3.判断参数值是否为admin
        if (value.equals("admin")){
            //4.是就放行            
           //chain是过滤器链,调这个方法类似于找到这个过滤器的下一个过滤器,调用他的filter方法
            return chain.filter(exchange);
        }else {
            //5.否就拦截
            //5.1、设置状态码
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            //5.2、拦截请求
            return exchange.getResponse().setComplete();
        }
    }
}

效果测试:

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring_15

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring cloud_16

 总结:

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_spring_17

 

 六、过滤器链的执行顺序

路由过滤器、DefaultFilter、GlobalFilter。

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_gateway_18

 

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_19

 七、跨域问题处理

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_20

spring cloud gateway 请求和相应头增加 spring cloud gateway 接口权限_java_21