SpringCloud_Gateway服务网关

这篇具有很好参考价值的文章主要介绍了SpringCloud_Gateway服务网关。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、SpringCloudGateway服务网关概论

1、SpringCloudGateway服务网关概论

Spring Cloud Gateway 用"Netty + Webflux"实现,不需要导入Web依赖。

  1. Webflux模式替换了旧的Servlet线程模型。用少量的线程处理request和response io操作,这些线程称为Loop线程,而业务交给响应式编程框架处理,响应式编程是非常灵活的,用户可以将业务中阻塞的操作提交到响应式框架的work线程中执行,而不阻塞的操作依然可以在Loop线程中进行处理,大大提高了Loop线程的利用率。
    即Webflux中的Loop线程不仅可以处理请求和响应请求,还可以对业务中不阻塞的操作进行处理,从而提高它的利用率。阻塞的操作由work线程进行处理。
  2. Webflux虽然可以兼容多个底层的通信框架,但是一般情况下,底层使用的还是Netty,毕竟,Netty是目前业界认可的最高性能的通信框架。
    Netty 是一个基于NIO的客户、服务器端的编程框架。提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
  3. Spring Cloud Gateway特点
    1)易于编写谓词( Predicates )和过滤器( Filters ) 。其Predicates和Filters
    可作用于特定路由。
    2)支持路径重写。
    3)支持动态路由。
    4)集成了Spring Cloud DiscoveryClient。

2、SpringCloudGateway的三大核心概念

  1. 路由(Route)
    这是网关的基本构建块。它由一个ID,一个目标URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
    即根据URL请求去匹配路由。
  2. 断言(predicate)
    输入类型是一个ServerWebExchange。我们可以使用它来匹配来自HTTP请求的任何内容,例如headers或参数。匹配请求内容。
    匹配完路由后,每个路由上面都会有断言,然后根据断言来判断是否可以进行路由。
  3. 过滤(filter)
    在匹配完路由和断言为真后,可以在请求被路由前或者之后对请求进行修改。
    即根据业务对其进行监控,限流,日志输出等等。

二、SpringCloudGateway的路由及断言

1、子模块项目SpringCloudGateway的搭建

  1. 在cloud父项目中新建一个模块Module,创建子模块网关cloud-gateway-gateway9527
    spring gateway网关,SpringCloud,spring cloud,gateway,java

  2. 在POM文件中添加如下依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>cloud</artifactId>
            <groupId>com.zzx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-gateway-gateway9527</artifactId>
    
        <properties>
            <maven.compiler.source>17</maven.compiler.source>
            <maven.compiler.target>17</maven.compiler.target>
        </properties>
        <dependencies>
            <!--  引入网关Gateway依赖   -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </dependency>
            <!--  引入Eureka client依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- actuator监控信息完善 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
        </dependencies>
    
    
    </project>
    
  3. 在gateway子模块中创建包com.zzx,在包下创建主启动类GatewayMain9527

    package com.zzx;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @Slf4j
    public class GatewayMain9527 {
        public static void main(String[] args) {
            SpringApplication.run(GatewayMain9527.class,args);
            log.info("************ GatewayMain9527服务 启动成功 *************");
        }
    }
    
    
  4. 在resources目录下创建application.yml文件,配置如下

    server:
      port: 9527
    spring:
      cloud:
        gateway:
          routes:
            # 路由ID,没有固定规则但要求唯一,建议配合服务名
            - id: cloud-payment-provider
              # 匹配后提供服务的路由地址 (即目标服务地址)
              uri: http://localhost:8001
              # 断言会接收一个输入参数,返回一个布尔值结果
              predicates:
                # 路径相匹配的进行路由
                - Path=/payment/*
    
    
  5. 测试
    1)先开启7001和7002的Eureka服务,payment8001服务提供者和gateway9527服务。
    2)在浏览器使用9527端口,也就是网关进行访问payment8001服务即可。
    在浏览器输入:http://localhost:9527/payment/index

2、SpringCloudGateway_Java API构建路由

  1. 在子模块cloud-gateway-gateway9527中的com.zzx包下,创建包config,并在包下创建GatewayConfig

    package com.zzx.config;
    
    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class GatewayConfig {
        @Bean
        public RouteLocator routeLocator(RouteLocatorBuilder builder){
            //获取路由
            RouteLocatorBuilder.Builder routes = builder.routes();
            /**
             * 设置路由
             * 1.路由id
             * 2.路由匹配规则
             * 3.目标地址
             */
            routes.route("path_route",r->r.path("/payment/*").uri("http://localhost:8001/")).build();
            return routes.build();
        }
    }
    
    
  2. 测试
    1)将yml文件中的gateway配置注释掉,然后重启该服务。
    2)在浏览器上访问:http://localhost:9527/payment/index

3、SpringCloudGateway的动态路由功能

  1. 再添加一个服务提供者,用以实现Gateway网关的动态路由的功能。
    1)复制payment8001服务,然后点击cloud父工程,ctrl+v进行粘贴,修改名字为8002
    2)修改POM文件:

    <artifactId>cloud-provider-payment8002</artifactId>
    

    3)将POM右键,选择添加为Maven项目Add as Maven Project
    spring gateway网关,SpringCloud,spring cloud,gateway,java
    4)修改com.zzx包下的启动类的名字以及类中的名字

    package com.zzx;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * 主启动类
     */
    @SpringBootApplication
    @Slf4j
    public class PaymentMain8002 {
        public static void main(String[] args) {
            SpringApplication.run(PaymentMain8002.class,args);
            log.info("****** PaymentMain8002服务启动成功 *****");
        }
    }
    
    

    5)将yml文件的端口号port和instance-id的名字有8001部分都修改为8002
    然后在启动类中运行该payment8002服务。

  2. 修改gateway9527项目的yml文件

    server:
      port: 9527
    
    eureka:
      instance:
        # 注册名
        instance-id: cloud-gateway-gateway9527
      client:
        service-url:
          # Eureka server的地址
          #集群
          defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
          #单机
          #defaultZone: http://localhost:7001/eureka/
    spring:
      application:
        #设置应用名
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            # 路由ID,没有固定规则但要求唯一,建议配合服务名
            - id: cloud-payment-provider
              # 匹配后提供服务的路由地址 (即目标服务地址) lb后跟提供服务的微服务的名字
              uri: lb://CLOUD-PAYMENT-PROVIDER
              # 断言会接收一个输入参数,返回一个布尔值结果
              predicates:
                # 路径相匹配的进行路由
                - Path=/payment/*
    
  3. 注释之前的配置文件GatewayConfig中的方法。

  4. 在服务提供者payment8001和payment8002中的com.zzx.controller的PaymentController类中添加如下代码

    @Value("${server.port}")
    private String port;
    @GetMapping("lb")
    public String lb(){
        return port;
    }
    

    即通过该lb的url请求来测试动态路由是否配置生效。

  5. 测试动态路由是否配置生效。
    1)重启payment8001和payment8002以及gateway9527服务
    2)浏览器中访问:http://localhost:9527/payment/lb
    spring gateway网关,SpringCloud,spring cloud,gateway,java
    spring gateway网关,SpringCloud,spring cloud,gateway,java
    此时刷新后随即出现8001或8002,估计是轮询的策略。

4、SpringCloudGateway的路由断言

  1. UTC时间格式的时间参数时间生成方法

    package demo;
    
    import java.time.ZonedDateTime;
    
    public class Test1 {
    	public static void main(String[] args) {
    		ZonedDateTime now = ZonedDateTime.now();
    		System.out.println(now);
    	}
    }
    
  2. Postman的下载地址:https://dl.pstmn.io/download/latest/win64
    Postman即用来URL请求测试的软件,可以很方便的添加任何请求参数。
    点击+号即可创建新的请求窗口,用来发送URL请求
    spring gateway网关,SpringCloud,spring cloud,gateway,java

  3. After路由断言

    predicates:
    	- Path=/payment/*
    	# 在这个时间点之后才能访问
    	- After=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
    

    即使用生成的UTC时间格式的时间,在该时间之后才允许访问。

  4. Before路由断言

    predicates:
    	- Path=/payment/*
    	 # 在这个时间点之前才能访问
        - Before=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
    

    即使用生成的UTC时间格式的时间,在该时间之前才允许访问。

  5. Between路由断言

    predicates:
    	- Path=/payment/*
    	# 在两个时间内才能访问
        - Between=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai],2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
    

    即使用生成的UTC时间格式的时间,在两个时间内才允许访问。

  6. Cookie路由断言
    1)Cookie验证的是Cookie中保存的信息,Cookie断言和上面介绍的两种断言使用方式大同小异,唯一的不同是它必须连同属性值一同验证,不能单独只验证属性是否存在。

    predicates:
    	- Path=/payment/*
    	- Cookie=username,zzx
    

    即Cookie的username的值为zzx才允许访问
    2)使用postman进行测试,在headers添加Cookie即可
    spring gateway网关,SpringCloud,spring cloud,gateway,java
    此时如果不带Cookie,则报404错误

  7. Header路由断言
    1)这个断言会检查Header中是否包含了响应的属性,通常可以用来验证请求是否携带了访问令牌。

    predicates:
    	- Path=/payment/*
    	- Header=X-Request-Id,\d+
    

    2)使用postman进行测试,在headers添加X-Request-Id即可
    spring gateway网关,SpringCloud,spring cloud,gateway,java

  8. Host路由断言
    1)Host 路由断言 Factory包括一个参数:host name列表。使用Ant路径匹配规则, .作为分隔符。访问的主机匹配http或者https, baidu.com 默认80端口, 就可以通过路由。 多个参数使用,号隔开。

    predicates:
    	- Path=/payment/*
    	- Host=127.0.0.1,localhost
    

    2)使用postman进行测试,在headers添加Host即可
    spring gateway网关,SpringCloud,spring cloud,gateway,java

  9. Method路由断言
    1)即Request请求的方式,例如GET或POST请求,不匹配则无法进行请求

    predicates:
    	- Path=/payment/*
    	- Method=GET,POST
    

    2)可以使用postman,也可以使用浏览器直接访问,因为不需要加任何参数

  10. Query路由断言
    1)请求断言也是在业务中经常使用的,它会从ServerHttpRequest中的Parameters列表中查询指定的属性,例如验证参数的类型等

    predicates:
    	- Path=/payment/*
    	- Query=age,\d+
    

    2)在参数Params中添加age属性,值为正整数即可访问
    spring gateway网关,SpringCloud,spring cloud,gateway,java

三、SpringCloudGateway的过滤器及跨域

1、SpringCloudGateway的过滤器

  1. 过滤器Filter
    在用户访问各个服务前,应在网关层统一做好鉴权、限流等工作。
    1)Filter的生命周期
    根据生命周期可以将Spring Cloud Gateway中的Filter分为"PRE"和"POST"两种。
    PRE:代表在请求被路由之前执行该过滤器,此种过滤器可用来实现参数校验、权限校验、流量监控、日志输出、协议转换等功能。
    POST:代表在请求被路由到微服务之后执行该过滤器。此种过滤器可用来实现响应头的修改(如添加标准的HTTP Header )、收集统计信息和指标、将响应发送给客户端、输出日志、流量监控等功能。
    即PRE是路由之前,POST是路由之后。
    2)Filter分类
    根据作用范围,Filter可以分为以下两种。
    GatewayFilter:网关过滤器,此种过滤器只应用在单个路由或者一个分组的路由上。
    GlobalFilter:全局过滤器,此种过滤器会应用在所有的路由上。

2、网关过滤器GatewayFilter

  1. 官方的配置文档:https://docs.spring.io/spring-cloud-gateway/docs/4.0.4/reference/html/#gatewayfilter-factories
  2. 使用内置过滤器SetStatus
    1)在yml文件中的filters下添加过滤器
    server:
      port: 9527
    
    eureka:
      instance:
        # 注册名
        instance-id: cloud-gateway-gateway9527
      client:
        service-url:
          # Eureka server的地址
          #集群
          defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
          #单机
          #defaultZone: http://localhost:7001/eureka/
    spring:
      application:
        #设置应用名
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            # 路由ID,没有固定规则但要求唯一,建议配合服务名
            - id: cloud-payment-provider
              # 匹配后提供服务的路由地址 (即目标服务地址) lb后跟提供服务的微服务的名字
              uri: lb://CLOUD-PAYMENT-PROVIDER
              # 断言会接收一个输入参数,返回一个布尔值结果
              predicates:
                # 路径相匹配的进行路由
                - Path=/payment/*
                # 在这个时间点之后才能访问
    #            - After=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
                # 在这个时间点之前才能访问
    #            - Before=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
                # 在两个时间内才能访问
    #            - Between=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai],2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
    #            - Cookie=username,zzx
    #            - Header=X-Request-Id,\d+
    #            - Host=127.0.0.1,localhost
    #            - Method=GET,POST
    #            - Query=age,\d+
              #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
              filters:
                # 修改原始响应的状态码
                - SetStatus=250
    
    2)在浏览器测试:http://localhost:9527/payment/lb
    spring gateway网关,SpringCloud,spring cloud,gateway,java
    此时响应码成功修改为250。

3、自定义网关过滤器GatewayFilter

  1. 在gateway9527服务的com.zzx.config包下,创建日志网关过滤器类LogGatewayFilterFactory

    package com.zzx.config;
    
    import lombok.Data;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.cloud.gateway.filter.GatewayFilter;
    import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * 日志网关过滤器
     */
    @Component
    @Slf4j
    public class LogGatewayFilterFactory extends AbstractGatewayFilterFactory<LogGatewayFilterFactory.Config> {
    
        public LogGatewayFilterFactory() {
            super(Config.class);
        }
    
        /**
         * 表示配置填写顺序
         * @return
         */
        @Override
        public List<String> shortcutFieldOrder() {
            return Arrays.asList("consoleLog");
        }
    
        /**
         * 执行过滤的逻辑
         * @param config
         * @return
         */
        @Override
        public GatewayFilter apply(Config config) {
            return ((exchange, chain) -> {
                if(config.consoleLog){
                    log.info("********* consoleLog日志 开启 ********");
                }
                return chain.filter(exchange);
            });
        }
    
        /**
         * 过滤器使用的配置内容
         *
         */
        @Data
        public static class Config{
            private boolean consoleLog;
        }
    
    }
    
    
  2. 在YML文件中,添加如下

    filters:
         # 控制日志是否开启
         - Log=true
    

    即开启日志,该true会被consoleLog获取到。 然后即可打印对应的日志。

  3. 测试
    1)重启Gateway9527服务
    2)在浏览器中访问:http://localhost:9527/payment/lb
    spring gateway网关,SpringCloud,spring cloud,gateway,java
    步骤:
    1、类名必须叫做XxxGatewayFilterFactory,注入到Spring容器后使用时的名称就叫做Xxx。
    2、创建一个静态内部类Config, 里面的属性为配置文件中配置的参数, - 过滤器名称=参数1,参数2…
    2、类必须继承 AbstractGatewayFilterFactory,让父类帮实现配置参数的处理。
    3、重写shortcutFieldOrder()方法,返回List参数列表为Config中属性集合
    return Arrays.asList(“参数1”,参数2…)
    4、无参构造方法中super(Config.class)
    5、编写过滤逻辑 public GatewayFilter apply(Config config)

4、自定义全局过滤器GlobalFilter

  1. 在gateway9527服务的com.zzx.config包下,创建用户鉴权全局过滤器类AuthGlobalFilter

    package com.zzx.config;
    
    import org.apache.commons.lang.StringUtils;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    /**
     * 用户鉴权全局过滤器
     */
    @Component
    public class AuthGlobalFilter implements GlobalFilter, Ordered {
        /**
         * 自定义全局过滤器逻辑
         * @param exchange
         * @param chain
         * @return
         */
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            //1。请求中获取Token令牌
            String token = exchange.getRequest().getQueryParams().getFirst("token");
            //2.判断token是否为空
            if(StringUtils.isEmpty(token)){
                System.out.println("鉴权失败,令牌为空");
                //将状态码设置为未授权
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            //3。判断token是否有效
            if(!token.equals("zzx")){
                System.out.println("token令牌无效");
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        }
    
        /**
         * 全局过滤器执行顺序 数值越小,优先级越高
         * @return
         */
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    
  2. 使用postman测试,在params中添加一个token进行测试
    spring gateway网关,SpringCloud,spring cloud,gateway,java

5、内置全局过滤器

  1. 官方的配置文档:https://docs.spring.io/spring-cloud-gateway/docs/4.0.4/reference/html/#global-filters
    SpringCloud Gateway内部也是通过一系列的内置全局过滤器对整个路由转发进行处理的。
  2. 路由过滤器(Forward)
  3. 路由过滤器(LoadBalancerClient)
  4. Netty路由过滤器
  5. Netty写响应过滤器(Netty Write Response F)
  6. RouteToRequestUrl 过滤器
  7. 路由过滤器 (Websocket Routing Filter)
  8. 网关指标过滤器(Gateway Metrics Filter)
  9. 组合式全局过滤器和网关过滤器排序(Combined Global Filter and GatewayFilter Ordering)
  10. 路由(Marking An Exchange As Routed)

6、服务网关Gateway实现跨域

  1. 跨域
    即当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

  2. 在resources目录下创建index.html文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
    </head>
    <body>
    
    
    </body>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <script>
    
    
      $.get("http://localhost:9527/payment/lb?token=zzx",function(data,status){
        alert("Data: " + data + "\nStatus: " + status);
       });
    </script>
    </html>
    
    
  3. 配置允许跨域
    1)在未配置允许跨域之前,打开该index.html文件时,如图
    spring gateway网关,SpringCloud,spring cloud,gateway,java
    2)在yml文件中配置允许跨域

    spring:
      cloud:
       gateway:
        globalcors:
         cors-configurations:
          '[/**]':
           allowCredentials: true
           allowedOriginPatterns: "*"
           allowedMethods: "*"
           allowedHeaders: "*"
         add-to-simple-url-handler-mapping: true
    
    

3)配置后,打开该index.html文件时,如图
spring gateway网关,SpringCloud,spring cloud,gateway,java

四、SpringCloudGateway实现用户鉴权

1、JsonWebToken概论

  1. JWT是一种用于双方之间传递安全信息的简洁的、URL安全的声明规范。定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。特别适用于分布式站点的单点登录(SSO)场景。

  2. JWT优点
    1)无状态
    2)适合移动端应用
    3)单点登录友好

  3. 用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候会加上签名,服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。

  4. JWT 的三个部分依次如下:
    1)头部(header)
    JSON对象,描述 JWT 的元数据。其中 alg 属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ 属性表示这个令牌(token)的类型(type),统一写为 JWT。

    {
     "alg": "HS256",
     "typ": "JWT"
    }
    

    2)载荷(payload)
    内容又可以分为3种标准
    1.标准中注册的声明
    iss: jwt签发者
    sub: jwt所面向的用户
    aud: 接收jwt的一方
    exp: jwt的过期时间,这个过期时间必须要大于签发时间
    nbf: 定义在什么时间之前,该jwt都是不可用的.
    iat: jwt的签发时间
    jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
    2.公共的声明
    公共的声明可以添加任何的信息。一般这里我们会存放一下用户的基本信息(非敏感信息)。
    3.私有的声明
    私有声明是提供者和消费者所共同定义的声明。需要注意的是,不要存放敏感信息
    base64编码,任何人获取到jwt之后都可以解码!!

    {
     "sub": "1234567890",
     "name": "John Doe",
     "iat": 1516239022
    }
    

    3)签证(signature)
    这部分就是 JWT 防篡改的精髓,其值是对前两部分base64UrlEncode 后使用指定算法签名生成,以默认 HS256 为例,指定一个密钥(secret),就会按照如下公式生成:

    HMACSHA256(
     base64UrlEncode(header) + "." + base64UrlEncode(payload),
     secret,
    )
    
  5. 客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。

2、创建用户的微服务及登录操作

  1. 在cloud父工程下,创建子模块项目cloud-auth-user6500
    spring gateway网关,SpringCloud,spring cloud,gateway,java

  2. 在cloud-auth-user6500项目的pom文件中引入依赖

     <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- redis -->
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- eureka client 依赖 -->
        <dependency>
     <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.22</version>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
         <!--   引入JWT依赖   -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.23</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.2.1</version>
        </dependency>
      </dependencies>
    
    
  3. 在com.zzx中创建一个包utils,创建工具类JWTUtils

    package com.zzx.utils;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTVerifier;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.exceptions.JWTVerificationException;
    import com.auth0.jwt.interfaces.DecodedJWT;
    
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    public class JWTUtils {
        // 签发人
        private static final String ISSUSER = "zzx";
        // 过期时间 1分钟
        private static final long TOKEN_EXPIRE_TIME = 60*1000;
        // 秘钥
        public static final String SECRET_KEY = "zzx-13256";
        /**
         * 生成令牌
         * @return
         */
        public static String token(){
            Date now = new Date();
            Algorithm hmac256 = Algorithm.HMAC256(SECRET_KEY);
            // 1.创建JWT
            String token = JWT.create().
                    // 签发人
                    withIssuer(ISSUSER)
                    // 签发时间
                    .withIssuedAt(now)
                    // 过期时间
                    .withExpiresAt(new Date(now.getTime()+TOKEN_EXPIRE_TIME))
                    // 加密算法
                    .sign(hmac256);
            return token;
        }
    
        /**
         * 验证令牌
         * @return
         */
        public static boolean verify(String token){
            try {
                Algorithm hmac256 = Algorithm.HMAC256(SECRET_KEY);
                JWTVerifier verifier = JWT.require(hmac256)
                        // 签发人
                        .withIssuer(ISSUSER)
                        .build();
                // 如果校验有问题则抛出异常
                DecodedJWT verify = verifier.verify(token);
                return true;
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (JWTVerificationException e) {
                e.printStackTrace();
            }
            return false;
        }
    
        public static void main(String[] args) throws InterruptedException {
            String token = token();
            System.out.println(token);
            boolean verify = verify(token);
            System.out.println(verify);
            verify = verify(token+" 11");
            System.out.println(verify);
            TimeUnit.SECONDS.sleep(61);
            verify = verify(token);
            System.out.println(verify);
    
        }
    }
    
    

    在该工具类JWTUtils中创建main方法用来测试该工具类。后面需要删掉。

  4. 在com.zzx中创建一个包common,创建类Result

    package com.zzx.common;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * 返回实体类
     */
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    @Builder
    public class Result {
        // 状态码
        private int code;
        // 描述信息
        private String msg;
        // token令牌
        private String token;
    }
    
    

    即用该类来封装返回值信息。

  5. 在com.zzx中创建一个包controller,创建控制层类UserController

    package com.zzx.controller;
    
    import com.zzx.common.Result;
    import com.zzx.utils.JWTUtils;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * 用户控制层
     */
    @RestController
    @RequestMapping("user")
    public class UserController {
        /**
         * 登录
         * @param username
         * @param password
         */
        @PostMapping("login")
        public Result login(String username, String password){
            // 1.验证用户名和密码
            // TODO 模拟数据库操作
            if("zzx".equals(username)&&"123456".equals(password)){
                // 2.生成令牌
                String token = JWTUtils.token();
                return Result.builder().code(200).msg("success").token(token).build();
            }else{
                return Result.builder().code(500).msg("用户名或密码不正确").build();
            }
        }
    }
    
    
  6. 在resources目录下创建一个application.yml配置文件

    server:
      port: 6500
    
    eureka:
      instance:
        # 注册名
        instance-id: cloud-auth-user6500
      client:
        service-url:
          # Eureka server的地址
          #集群
          defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
          #单机
          #defaultZone: http://localhost:7001/eureka/
    spring:
      application:
        #设置应用名
        name: cloud-auth-user
    
  7. 在com.zzx中,修改主启动类Main,修改为UserMain6500

    package com.zzx;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * 主启动类
     */
    @Slf4j
    @SpringBootApplication
    public class UserMain6500 {
        public static void main(String[] args) {
            SpringApplication.run(UserMain6500.class,args);
            log.info("************ UserMain6500服务 启动成功 ************");
        }
    }
    
  8. 测试User控制层的login方法
    1)启动eureka服务eureka7001和eureka7002以及user6500
    spring gateway网关,SpringCloud,spring cloud,gateway,java

2)在postman中,使用POST请求传入用户名和密码,对该url进行测试
spring gateway网关,SpringCloud,spring cloud,gateway,java

3、服务网关Gateway实现用户鉴权

即在网关过滤器中加入JWT来鉴权

  1. 在gateway9527项目的POM文件中添加JWT依赖

     <!--   引入JWT依赖     -->
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>2.0.23</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>java-jwt</artifactId>
                <version>4.2.1</version>
            </dependency>
    
  2. 将user6500项目中com.zzx.utils包下的JWTUtils复制到gateway9527项目的com.zzx.utils包下

    package com.zzx.utils;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTVerifier;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.exceptions.JWTVerificationException;
    import com.auth0.jwt.interfaces.DecodedJWT;
    
    import java.util.Date;
    
    public class JWTUtils {
        // 签发人
        private static final String ISSUSER = "zzx";
        // 过期时间 1分钟
        private static final long TOKEN_EXPIRE_TIME = 60*1000;
        // 秘钥
        public static final String SECRET_KEY = "zzx-13256";
        /**
         * 生成令牌
         * @return
         */
        public static String token(){
            Date now = new Date();
            Algorithm hmac256 = Algorithm.HMAC256(SECRET_KEY);
            // 1.创建JWT
            String token = JWT.create().
                    // 签发人
                    withIssuer(ISSUSER)
                    // 签发时间
                    .withIssuedAt(now)
                    // 过期时间
                    .withExpiresAt(new Date(now.getTime()+TOKEN_EXPIRE_TIME))
                    // 加密算法
                    .sign(hmac256);
            return token;
        }
    
        /**
         * 验证令牌
         * @return
         */
        public static boolean verify(String token){
            try {
                Algorithm hmac256 = Algorithm.HMAC256(SECRET_KEY);
                JWTVerifier verifier = JWT.require(hmac256)
                        // 签发人
                        .withIssuer(ISSUSER)
                        .build();
                // 如果校验有问题则抛出异常
                DecodedJWT verify = verifier.verify(token);
                return true;
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (JWTVerificationException e) {
                e.printStackTrace();
            }
            return false;
        }
    
    }
    
    
  3. 修改application.yml文件

    server:
      port: 9527
    
    eureka:
      instance:
        # 注册名
        instance-id: cloud-gateway-gateway9527
      client:
        service-url:
          # Eureka server的地址
          #集群
          defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
          #单机
          #defaultZone: http://localhost:7001/eureka/
    
    org:
      my:
        jwt:
          # 跳过认证路由
          skipAuthUrls:
            - /user/login
    
    spring:
      application:
        #设置应用名
        name: cloud-gateway
      cloud:
        gateway:
          # 路由配置
          routes:
            # 路由ID,没有固定规则但要求唯一,建议配合服务名
            - id: cloud-auth-user
              # 匹配后提供服务的路由地址 (即目标服务地址) lb后跟提供服务的微服务的名字
              uri: lb://CLOUD-AUTH-USER
              # 断言会接收一个输入参数,返回一个布尔值结果
              predicates:
                # 路径相匹配的进行路由
                - Path=/user/*
            # 路由ID,没有固定规则但要求唯一,建议配合服务名
            - id: cloud-payment-provider
              # 匹配后提供服务的路由地址 (即目标服务地址) lb后跟提供服务的微服务的名字
              uri: lb://CLOUD-PAYMENT-PROVIDER
              # 断言会接收一个输入参数,返回一个布尔值结果
              predicates:
                # 路径相匹配的进行路由
                - Path=/payment/*
                # 在这个时间点之后才能访问
    #            - After=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
                # 在这个时间点之前才能访问
    #            - Before=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
                # 在两个时间内才能访问
    #            - Between=2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai],2030-04-28T11:50:49.213572400+08:00[Asia/Shanghai]
    #            - Cookie=username,zzx
    #            - Header=X-Request-Id,\d+
    #            - Host=127.0.0.1,localhost
    #            - Method=GET,POST
    #            - Query=age,\d+
              #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
              filters:
                # 修改原始响应的状态码
    #            - SetStatus=250
                # 控制日志是否开启
                - Log=true
          globalcors:
            cors-configurations:
              '[/**]':
                allowCredentials: true
                allowedOriginPatterns: "*"
                allowedMethods: "*"
                allowedHeaders: "*"
            add-to-simple-url-handler-mapping: true
    

    即需要添加一个user微服务的路由,以及跳过权限验证的Path路径

  4. 将gateway9527项目的com.zzx.config包下原先的用户鉴权类AuthGlobalFilter上面的@Component注解注释掉,即不使用这个类来鉴权;创建使用另一个类UserAuthGlobalFilter来鉴权

    package com.zzx.config;
    
    import com.alibaba.fastjson.JSONObject;
    import com.zzx.common.Response;
    import com.zzx.utils.JWTUtils;
    import io.micrometer.common.util.StringUtils;
    import lombok.Data;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.core.io.buffer.DataBuffer;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.server.reactive.ServerHttpResponse;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    import java.nio.charset.StandardCharsets;
    
    /**
     * 用户鉴权全局过滤器
     */
    @Data
    @ConfigurationProperties("org.my.jwt")
    @Component
    @Slf4j
    public class UserAuthGlobalFilter implements GlobalFilter, Ordered {
        private String[] skipAuthUrls;
        /**
         * 过滤器逻辑
         * @param exchange
         * @param chain
         * @return
         */
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 获取请求url地址
            String path = exchange.getRequest().getURI().getPath();
            // 跳过不需要验证的路径
            if(skipAuthUrls!=null && isSKip(path)){
                return chain.filter(exchange);
            }
            // 1.从请求头中获取token
            String token = exchange.getRequest().getHeaders().getFirst("token");
            // 2.判断token
            if(StringUtils.isEmpty(token)){
                // 3.设置响应
                ServerHttpResponse response = exchange.getResponse();
                // 4.设置响应状态码
                response.setStatusCode(HttpStatus.OK);
                // 5.设置响应头
                response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
                // 6.创建响应对象
                Response res = new Response(200, "token 参数缺失");
                // 7.对象转字符串
                byte[] bytes = JSONObject.toJSONString(res).getBytes(StandardCharsets.UTF_8);
                // 8.数据流返回数据
                DataBuffer wrap = response.bufferFactory().wrap(bytes);
                return response.writeWith(Flux.just(wrap));
    
            }
            // 验证token
            boolean verify = JWTUtils.verify(token);
            if(!verify){
                // 3.设置响应
                ServerHttpResponse response = exchange.getResponse();
                // 4.设置响应状态码
                response.setStatusCode(HttpStatus.OK);
                // 5.设置响应头
                response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
                // 6.创建响应对象
                Response res = new Response(200, "token 失效");
                // 7.对象转字符串
                byte[] bytes = JSONObject.toJSONString(res).getBytes(StandardCharsets.UTF_8);
                // 8.数据流返回数据
                DataBuffer wrap = response.bufferFactory().wrap(bytes);
                return response.writeWith(Flux.just(wrap));
            }
            // token 令牌通过
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    
        private boolean isSKip(String url){
            for (String skipAuthUrl :skipAuthUrls) {
                if(url.startsWith(skipAuthUrl)){
                    return true;
                }
            }
            return false;
        }
    }
    
    
  5. 测试
    1)先启动eureka7001和eureka7002,还有Payment8001和Payment8002,以及user6500和gateway9527服务。
    spring gateway网关,SpringCloud,spring cloud,gateway,java

2)使用postman工具来测试,先进行登录,拿到用户的token
spring gateway网关,SpringCloud,spring cloud,gateway,java
3)再切换到之前9527的url测试
token有效时
spring gateway网关,SpringCloud,spring cloud,gateway,java
token过期失效时
spring gateway网关,SpringCloud,spring cloud,gateway,java
没有token时(即未登录时)
spring gateway网关,SpringCloud,spring cloud,gateway,java文章来源地址https://www.toymoban.com/news/detail-785423.html

总结

  1. Spring Cloud Gateway 用"Netty + Webflux"实现,不需要导入Web依赖。
    1)Webflux模式替换了旧的Servlet线程模型。用少量的线程处理request和response io操作,这些线程称为Loop线程。Webflux中的Loop线程不仅可以处理请求和响应请求,还可以对业务中不阻塞的操作进行处理,从而提高它的利用率。阻塞的操作由work线程进行处理。
    Webflux底层使用的还是Netty,Netty是目前业界认可的最高性能的通信框架。
    2)SpringCloudGateway的三大核心概念,分别是路由、断言、过滤。
    即根据url请求进行匹配到指定路由;每个路由上面都有断言,根据断言来判断是否可以进行路由;最后对该url请求进行一个过滤,例如监控、限流和日志输出等操作。
  2. 1)SpringCloudGateway的搭建,需要先引入依赖,然后创建主启动类,最后配置Gateway的配置文件。- id属性值需要唯一;uri的属性值即对应的服务器ip地址+端口号;predicates断言的属性值,例如OrderController第一层@RequestMapping注解的url属性值,即判断url是否跟该值一致。
    2)服务网关Gateway通过Java API构建时需要实现RouteLocator接口构建路由规则。即先将yml文件中等价的gateway配置注释掉,然后创建一个config配置类,在配置类中,创建一个方法使用RouteLocator接口来构建路由。并在该方法上添加@Bean注解,即由SpringIOC容器进行管理。
    3)SpringCloudGateway的动态路由功能,即在yml文件中将原本路由的uri改成lb://服务提供者的微服务的名字;然后需要引入EureakaClient和Gateway等依赖即可实现Gateway的动态路由功能。
    也就是说需要配置和使用Eureka,但是可以设置不把自身注册到Eureka服务中。
    4)SpringCloudGateway的路由断言,路由断言分别有After、Before、Between、Cookie、Header、Host、Method、Query等。其中After、Before、Between都是跟时间有关的;Cookie、Header、Host都是在头文件Headers中携带的参数;Method是匹配指定的请求方法;Query是在Params中检查参数的合法性。
    断言是在YML文件的spring.cloud.gateway.routes.predicates下进行配置的。
    5)SpringCloudGateway的过滤器,在用户访问各个服务前,应在网关层统一做好鉴权、限流等工作。过滤器Filter的生命周期分为PRE和POST,即PRE是路由之前,POST是路由之后。它作用范围分为GatewayFilter和GlobalFilter,即GatewayFilter是网关路由器,是应用在单个路由或一个分组的路由上的,而GlobalFilter是全局路由器,会应用在所有路由上的。
  3. 1)内置过滤器,即在YML文件中,在filters下添加内置过滤器。
    2)自定义网关过滤器,即需要创建一个配置类,类名必须叫做XxxGatewayFilterFactory,在该类上使用@Component注解;该类需要创建一个静态内部类Config,里面的属性为配置文件中配置的参数;必须继承AbstractGatewayFilterFactory;重写shortcutFieldOrder()方法,返回List参数列表为Config中属性集合;创建无参构造方法,方法体为super(Config.class);编写过滤逻辑 public GatewayFilter apply(Config config)。
    3)自定义全局过滤器,当客户端第一次请求服务时,服务端对用户进行信息认证(登录);认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证;以后每次请求,客户端都携带认证的token;服务端对token进行解密,判断是否有效,有效则继续允许访问服务,无效则不允许访问服务。
    此时需要实现GlobalFilter, Ordered接口,一个是全局过滤器接口,一个是全局过滤器执行顺序的接口。
    即在Ordered接口的实现类中返回一个数值,该值越小,当前过滤器的优先级越高。
    GlobalFilter接口的实现类,对请求参数进行一个过滤操作。
  4. 1)配置跨域,即在yml文件配置允许跨域即可。
    2)JsonWebToken,是一种用于双方之间传递安全信息的简洁的、URL安全的声明规范。适用于分布式的单点登录(SSO)。
    客户端收到服务器返回的 JWT,会把数据保存到loadStorage。JWT签证默认的算法是 HMAC SHA256(HS256)。
    3)用户登录并生成token返回的业务流程,登录成功时JWT的Token通过JWTUtils工具类生成,状态码为200,消息为成功,以及返回值的类型需要封装为Result实体类;登录失败时不生成token,状态码500,消息为用户名或密码错误,同时返回值的类型也是需要封装为Result实体类。此时该方法为Post请求,因为涉及帐号信息。
    并且需要引入JWT和fastjson依赖。
  5. 使用gateway网关进行用户鉴权,在application.yml文件中配置跳过login登录的鉴权,即其他的url请求都要进行用户鉴权;需要引入JWT和fastjson的依赖;使用JWTUtils的生成token方法以及验证token是否有效的方法;在用户鉴权时,需要先获取跳过的路径,进行匹配,匹配成功则跳过鉴权进行下一步的业务操作;匹配失败,则说明该请求需要验证token,首先需要从request请求的请求头中获取token,如果token为空,则返回一个response对象,包含状态码和字符串消息;如果token不为空,则进行下一步验证,即使用JWTUtils的token验证方法,如果返回false,则表示token无效或者失效,则返回一个response对象,包含状态码和字符串消息;如果token不为空且token有效,则进行下一步的业务操作。
    即用户鉴权,实际上就判断该请求是否需要跳过鉴权,以及token是否为空和token是否有效的操作。

到了这里,关于SpringCloud_Gateway服务网关的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloud - GateWay服务网关

    gateway 官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/ 在微服务架构中,一个系统往往由多个微服务组成,而这些服务可能部署在不同机房、不同地区、不同域名下。这种情况下,客户端(例如浏览器、手机、软件工具等)想要直接请求这些服务

    2024年02月07日
    浏览(52)
  • 【SpringCloud技术专题】「Gateway网关系列」(2)微服务网关服务的Gateway功能配置指南分析

    Spring Cloud Gateway简介 Spring Cloud Gateway是Spring Cloud体系的第二代网关组件,基于Spring 5.0的新特性WebFlux进行开发,底层网络通信框架使用的是Netty,所以其吞吐量高、性能强劲,未来将会取代第一代的网关组件Zuul。 Spring Cloud Gateway可以通过服务发现组件自动转发请求,默认集成了

    2024年02月11日
    浏览(37)
  • 微服务网关 —— SpringCloud Gateway

    Spring Cloud Gateway 基于 Spring 5、Spring Boot 2 和 Project Reactor 等技术,是在 Spring 生态系统之上构建的 API 网关服务,Gateway 旨在提供一种简单而有效的方式来对 API 进行路由以及提供一些强大的过滤器功能,例如熔断、限流、重试等 Spring Cloud Gateway 具有如下特性: 基于 Spring Frame

    2024年02月10日
    浏览(50)
  • 【SpringCloud技术专题】「Gateway网关系列」(1)微服务网关服务的Gateway组件的原理介绍分析

    为什么要有服务网关? 我们都知道在微服务架构中,系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?难道要一个个的去调用吗?很显然这是不太实际的,我们需要有一个统一的接口与这些微服务打交道,这就是我们需要服务网关的原因。 我们

    2024年02月11日
    浏览(47)
  • SpringCloud第三篇:GateWay服务网关

          传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。那有了网关之后

    2024年02月08日
    浏览(48)
  • SpringCloud基础篇-10-服务网关-Gateway

    上一代网关Zuul 官网 SpringCloudGateway官网,变化很大,以实际为准 Gateway是在Spring生态系统之上构建的API网关服务,基于Spring5SpringBoot2和ProjectReactor等技术。 Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等 SpringCl

    2024年04月11日
    浏览(43)
  • day08-SpringCloud Gateway-服务网关

    没有使用网关服务时: 使用网关服务后: 官网:Spring Cloud Gateway Gateway是Spring生态系统之上构建的API网关服务,基于Spring、SpringBoot和Project Reactor等技术 Gateway旨在提供一种简单有效的方式来对API进行路由,以及提供一切强大的过滤器功能,例如:熔断、限流、重试等 鉴权 流

    2024年02月07日
    浏览(42)
  • SpringCloud微服务 【实用篇】| 统一网关Gateway

    目录 一:统一网关Gateway 1. 为什么需要网关 2. gateway快速入门 3. 断言工厂 4. 过滤器工厂 5. 全局过滤器 6. 跨域问题 前面我们已经学习了注册中心Eureka、Nacos和配置管理中心Nacos;但是此时存在很多安全的问题,服务器摆在那里谁都可以进行访问! 网关功能: ① 身份认证和权

    2024年02月04日
    浏览(43)
  • SpringCloud之微服务API网关Gateway介绍

    1.1.1 简介 如果没有网关,难道不行吗?功能上是可以的,我们直接调用提供的接口就可以了。那为什么还需要网关? 因为网关的作用不仅仅是转发请求而已。我们可以试想一下,如果需要做一个请求认证功能,我们可以接入到 API 服务中。但是倘若后续又有服务需要接入,我

    2024年02月14日
    浏览(50)
  • SpringCloud Alibaba入门7之引入服务网关Gateway

    我们需要在客户端和服务端之间加一个统一的入口,来作为请求的统一接入,而在微服务的体系中,承担这个角色的就是网关。我们只需要将网关的机器IP配置到DNS,或者接入负载,那么客户端的服务最终通过我们的网关,再转发到对应的服务端服务。 一、创建网关服务  1.引

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包