国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān)

這篇具有很好參考價(jià)值的文章主要介紹了【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

系列博客

【Spring Cloud一】微服務(wù)基本知識(shí)
【Spring Cloud 三】Eureka服務(wù)注冊與服務(wù)發(fā)現(xiàn)
【Spring Cloud 四】Ribbon負(fù)載均衡
【Spring Cloud 五】OpenFeign服務(wù)調(diào)用
【Spring Cloud 六】Hystrix熔斷
【Spring Cloud 七】Sleuth+Zipkin 鏈路追蹤

背景

在項(xiàng)目中是使用了Gateway做統(tǒng)一的請求的入口,以及統(tǒng)一的跨域處理以及統(tǒng)一的token校驗(yàn)。但是這些工作都是之前的同事來做的,正好在新項(xiàng)目中也需要使用其進(jìn)行統(tǒng)一的token校驗(yàn)。本著對Gateway更精進(jìn)一步所以博主就對Gateway進(jìn)行了較為全面的學(xué)習(xí)了解,包括動(dòng)態(tài)路由、自定義過濾器、token校驗(yàn)和續(xù)活。

一、什么是Spring Cloud Gateway

Spring Cloud Gateway提供一種簡單有效的方法來路由到對應(yīng)的API上,并可以提供一些額外的功能,安全性、監(jiān)控、度量、負(fù)載等等。

我們可以這樣理解,Spring Cloud Gateway將該項(xiàng)目中所有服務(wù)對外提供的API聚集起來,并向外提供唯一的入口,同時(shí)提供了一些額外的功能,安全性、監(jiān)控、度量、負(fù)載等等。

沒使用Spring Cloud Gateway 之前的示意圖
【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway
使用Spring Cloud Gateway之后的示意圖:
【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

二、為什么要使用Spring Cloud Gateway

  1. 統(tǒng)一入口并解除客戶端與服務(wù)端的耦合:在微服務(wù)架構(gòu)中,每個(gè)微服務(wù)都有自己入口,在沒有它的時(shí)候客戶端需要大量微服務(wù)的地址,會(huì)照成復(fù)雜的客戶端代碼。并且會(huì)暴露服務(wù)端的細(xì)節(jié),如果服務(wù)端發(fā)生變化,可能會(huì)影響到客戶端代碼,導(dǎo)致維護(hù)困難。
  2. 動(dòng)態(tài)路由和負(fù)載均衡:Spring Cloud GateWay 提供動(dòng)態(tài)路由來應(yīng)對當(dāng);網(wǎng)關(guān)來能夠在多個(gè)服務(wù)實(shí)例之間進(jìn)行負(fù)載均衡,提供整個(gè)系統(tǒng)的高可用。
  3. 請求過濾:在微服務(wù)架構(gòu)中,可能需要對請求進(jìn)行鑒權(quán)、身份驗(yàn)證一個(gè)中心化的地方來處理這些請求過濾和處理邏輯可以減少重復(fù)的代碼和邏輯。
  4. 反應(yīng)式和高性能:由于微服務(wù)架構(gòu)的復(fù)雜性,需要一個(gè)能夠處理高并發(fā)請求的解決方案,以確保系統(tǒng)在高負(fù)載情況下保持穩(wěn)定。Spring Cloud Gateway是基于webFlux框架實(shí)現(xiàn)的,而webFlux框架底層使用了高性能Reactor模式通信框架的Netty。

三、 Spring Cloud Gateway 三大核心概念

4.1 Route(路由)

路由是由一個(gè)ID、一個(gè)目的URI、一組斷言、一組Filter組成。
如果路由斷言為真,那么說明這個(gè)路由被匹配上了。

4.2 Predicate(斷言)

是一個(gè)java8函數(shù)斷言。輸入類型是一個(gè)Spring Framewordk ServerWebExchange??梢宰屇闫ヅ銱TTP上的任何請求。比如請求頭和參數(shù)。

4.3 Filter(過濾)

是Spring WebFilter的實(shí)例,Spring Cloud Gateway中的Filter分為兩種,分貝是Gateway Filter和Global Filter(一個(gè)是針對某一個(gè)路由的filter,例如對某一個(gè)接口做限流;一個(gè)是針對全局的filter,例如token校驗(yàn),ip黑名單)。過濾器Filter將會(huì)對請求和響應(yīng)進(jìn)行修改處理。

五、Spring Cloud Gateway是如何工作的

Spring 官網(wǎng)
【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway
客戶端向Spring Cloud Gateway發(fā)出請求。如果網(wǎng)關(guān)處理器映射器確定請求與路由匹配,則會(huì)將其發(fā)送到網(wǎng)關(guān)web處理器。它通過特定的過濾器鏈來運(yùn)行請求。過濾器被虛線分割的原因是過濾器可以在發(fā)送代理請求之前和之后運(yùn)行對應(yīng)的邏輯。

四、 如何使用Spring Cloud Gateway進(jìn)行服務(wù)路由

示例項(xiàng)目示意圖:
【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway
備注:Eureka的搭建可以參考這篇博客:【Spring Cloud 三】Eureka服務(wù)注冊與服務(wù)發(fā)現(xiàn)

這里之所以使用Eureka是為了之后做動(dòng)態(tài)路由和負(fù)載均衡。

4.1搭建服務(wù)A

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.12.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.wangwei</groupId>
	<artifactId>login-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>login-service</name>
	<description>login-service</description>
	<properties>
		<java.version>8</java.version>
		<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
	</properties>
	<dependencies>

<!--		<dependency>-->
<!--			<groupId>org.springframework.boot</groupId>-->
<!--			<artifactId>spring-boot-starter-data-redis</artifactId>-->
<!--		</dependency>-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

yml配置文件

server:
  port: 8081

spring:
  application:
    name: login-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
    register-with-eureka: true #設(shè)置為fasle 不往eureka-server注冊,默認(rèn)為true
    fetch-registry: true #應(yīng)用是否拉取服務(wù)列表到本地
    registry-fetch-interval-seconds: 10 #為了緩解服務(wù)列表的臟讀問題,時(shí)間越短臟讀越少 性能相應(yīng)的消耗回答


  instance: #實(shí)例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
    hostname: localhost #主機(jī)名稱或者服務(wù)ip
    prefer-ip-address: true #以ip的形式顯示具體的服務(wù)信息
    lease-renewal-interval-in-seconds: 10 #服務(wù)實(shí)例的續(xù)約時(shí)間間隔


啟動(dòng)類

@SpringBootApplication
@EnableEurekaClient
public class LoginServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(LoginServiceApplication.class, args);
	}

}

controller類

@RestController
public class LoginController {
    @GetMapping("doLogin")
    public String doLogin(){
       return "登陸成功";
    }
}

4.2 搭建服務(wù)B

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wangwei</groupId>
    <artifactId>teacher-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>teacher-service</name>
    <description>teacher-service</description>
    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

yml配置文件

server:
  port: 8082

spring:
  application:
    name: teacher-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
    register-with-eureka: true #設(shè)置為fasle 不往eureka-server注冊,默認(rèn)為true
    fetch-registry: true #應(yīng)用是否拉取服務(wù)列表到本地
    registry-fetch-interval-seconds: 10 #為了緩解服務(wù)列表的臟讀問題,時(shí)間越短臟讀越少 性能相應(yīng)的消耗回答


  instance: #實(shí)例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
    hostname: localhost #主機(jī)名稱或者服務(wù)ip
    prefer-ip-address: true #以ip的形式顯示具體的服務(wù)信息
    lease-renewal-interval-in-seconds: 10 #服務(wù)實(shí)例的續(xù)約時(shí)間間隔

啟動(dòng)類

@SpringBootApplication
@EnableEurekaClient
public class TeacherServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(TeacherServiceApplication.class, args);
    }

}

controller類

@RestController
public class TeacherController {
    @GetMapping("teach")
    public String teach(){
        return "教書學(xué)習(xí)";
    }
}

4.3搭建Spring Cloud Gateway服務(wù)

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.12.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.wangwei</groupId>
	<artifactId>gateway-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>gateway-server</name>
	<description>gateway-server</description>
	<properties>
		<java.version>8</java.version>
		<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
	</properties>
	<dependencies>
<!--		<dependency>-->
<!--			<groupId>org.springframework.boot</groupId>-->
<!--			<artifactId>spring-boot-starter-data-redis</artifactId>-->
<!--		</dependency>-->
<!--		<dependency>-->
<!--			<groupId>org.springframework.boot</groupId>-->
<!--			<artifactId>spring-boot-starter-data-redis-reactive</artifactId>-->
<!--		</dependency>-->

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

yml配置文件

server:
  port: 81 #?????80


spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true
      routes:
        - id: login-service-route # 路由的id  保持唯一
          uri: http://localhost:8081 #uri統(tǒng)一資源標(biāo)識(shí)符  url 統(tǒng)一資源定位符
          #uri: lb://login-service #??lb負(fù)載均衡
          predicates: # 斷言是給某一個(gè)路由來設(shè)定的一種匹配規(guī)則 默認(rèn)不能作用在動(dòng)態(tài)路由上
            - Path=/doLogin # 匹配規(guī)則 只要你Path配置上了/doLogin 就往uri轉(zhuǎn)發(fā)并將路徑帶上
        - id: teacher-service-route
          url:  http://localhost:8082
          predicates:
            - Path=/teach



eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
    register-with-eureka: true #設(shè)置為fasle 不往eureka-server注冊,默認(rèn)為true
    fetch-registry: true #應(yīng)用是否拉取服務(wù)列表到本地
    registry-fetch-interval-seconds: 10 #為了緩解服務(wù)列表的臟讀問題,時(shí)間越短臟讀越少 性能相應(yīng)的消耗回答


  instance: #實(shí)例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
    hostname: localhost #主機(jī)名稱或者服務(wù)ip
    prefer-ip-address: true #以ip的形式顯示具體的服務(wù)信息
    lease-renewal-interval-in-seconds: 10 #服務(wù)實(shí)例的續(xù)約時(shí)間間隔



啟動(dòng)類

@SpringBootApplication
@EnableEurekaClient
public class GatewayServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(GatewayServerApplication.class, args);
	}

}

4.4啟動(dòng)項(xiàng)目

依次啟動(dòng)Eureka服務(wù),gateway服務(wù)和兩個(gè)服務(wù)A和服務(wù)B。

進(jìn)行調(diào)用服務(wù)A和服務(wù)B:
如下圖所示通過gateway的ip+端口+路徑調(diào)用到對應(yīng)的服務(wù)A中和服務(wù)B中。

【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

4.5動(dòng)態(tài)路由

在微服務(wù)中通常一個(gè)服務(wù)的實(shí)例有多個(gè),那我們網(wǎng)關(guān)如何做負(fù)載均衡呢?
gateway幫我們做了很多東西,只要我們集成注冊中心(nacos、Eureka、zoomkeeper)并添加對應(yīng)的配置gateway就可以自動(dòng)幫我們進(jìn)行負(fù)載均衡。

方式一:
添加對應(yīng)的配置信息,來開啟動(dòng)態(tài)路由

    gateway:
      enabled: true
      routes:
        - id: login-service-route # 路由的id  保持唯一
          uri: http://localhost:8081 #uri統(tǒng)一資源標(biāo)識(shí)符  url 統(tǒng)一資源定位符
          #uri: lb://login-service #??lb負(fù)載均衡
          predicates: # 斷言是給某一個(gè)路由來設(shè)定的一種匹配規(guī)則 默認(rèn)不能作用在動(dòng)態(tài)路由上
            - Path=/doLogin # 匹配規(guī)則 只要你Path配置上了/doLogin 就往uri轉(zhuǎn)發(fā)并將路徑帶上
        - id: teacher-service-route
          uri:  http://localhost:8082
          predicates:
            - Path=/teach
      discovery:
        locator:
          enabled: true #開啟動(dòng)態(tài)路由  開啟通過應(yīng)用名稱找到服務(wù)的功能
          lower-case-service-id: true  # 開啟服務(wù)名稱小寫

請求服務(wù)時(shí)需要帶上對應(yīng)的服務(wù)名稱
【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

方式二:
添加對應(yīng)的配置:uri: lb://login-service #lb負(fù)載均衡

    gateway:
      enabled: true
      routes:
        - id: login-service-route # 路由的id  保持唯一
          #uri: http://localhost:8081 #uri統(tǒng)一資源標(biāo)識(shí)符  url 統(tǒng)一資源定位符
          uri: lb://login-service #lb負(fù)載均衡
          predicates: # 斷言是給某一個(gè)路由來設(shè)定的一種匹配規(guī)則 默認(rèn)不能作用在動(dòng)態(tài)路由上
            - Path=/doLogin # 匹配規(guī)則 只要你Path配置上了/doLogin 就往uri轉(zhuǎn)發(fā)并將路徑帶上
        - id: teacher-service-route
          uri:  http://localhost:8082
          predicates:
            - Path=/teach

【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

推薦使用方式一進(jìn)行統(tǒng)一的配置負(fù)載均衡。

五、gateway過濾器

過濾器按照作用范圍可以分為兩種,Gateway Filter和Global Filter。

Gateway Filter:網(wǎng)關(guān)過濾器需要通過 spring.cloud.routes.filters 配置在具體路由下,只作用在當(dāng)前路由上或通過 spring.cloud.default-filters 配置在全局,作用在所有路由上。

Global Filter:全局過濾器,不需要配置路由,系統(tǒng)初始化作用在所有路由上。

全局過濾器一般用于:統(tǒng)計(jì)請求次數(shù)、限流、token校驗(yàn)、ip黑名單攔截等。

5.1自定義全局過濾器

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    /**
     * 過濾的方法
     * 職責(zé)鏈模式
     * 網(wǎng)關(guān)里面有使用 mybatis的二級(jí)緩存有變種職責(zé)鏈模式
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //針對請求的過濾 拿到請求 header url 參數(shù)。。。
        ServerHttpRequest request = exchange.getRequest();
        //HttpServletRequest 這個(gè)是web里面的
        //ServerHttpRequest webFlux里面 響應(yīng)式里面的
        String path=request.getURI().getPath();
        System.out.println(path);
        HttpHeaders headers=request.getHeaders();
        System.out.println(headers);
        String name = request.getMethod().name();
        String hostString = request.getHeaders().getHost().getHostString();
        System.out.println(hostString);

        //響應(yīng)相關(guān)數(shù)據(jù)
        ServerHttpResponse response = exchange.getResponse();
        //微服務(wù) 肯定是前后端分離的 一般前后端通過數(shù)據(jù)傳輸是json格式
        //{"code":200,"msg":"ok"}
        //設(shè)置編碼 響應(yīng)頭

        response.getHeaders().set("content-type","application/json;charset=utf-8");
        //組裝業(yè)務(wù)返回值
        HashMap<String ,Object> map=new HashMap<>(4);
        map.put("code", HttpStatus.UNAUTHORIZED.value());
        map.put("msg","你未授權(quán)");
        ObjectMapper objectMapper=new ObjectMapper();
        //把一個(gè)map轉(zhuǎn)換為字節(jié)
        byte[] bytes = new byte[0];
        try {
            bytes = objectMapper.writeValueAsBytes(map);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        //通過buffer工廠將字節(jié)數(shù)組包裝成一個(gè)數(shù)據(jù)報(bào)
        DataBuffer wrap = response.bufferFactory().wrap(bytes);
        return response.writeWith(Mono.just(wrap));
        //放行,到下一個(gè)過濾器
        //return chain.filter(exchange);
    }

    /**
     * 制定順序的方法
     * 越小越先執(zhí)行
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

請求接口進(jìn)行訪問,可以發(fā)現(xiàn)當(dāng)前請求已經(jīng)被攔截下來。

【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

六、使用gateway做token校驗(yàn)

6.1實(shí)現(xiàn)的大致流程示意圖:

6.2實(shí)現(xiàn)代碼

gateway服務(wù)

pom.xml文件

在pom文件中新增redis的依賴

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

注意博主是在本機(jī)安裝的redis所以不需要在服務(wù)中添加對應(yīng)的redis配置。

TokenCheckFilter類

新建TokenCheckFilter類并實(shí)現(xiàn)全局過濾器和Ordered

package com.wangwei.gatewayserver.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
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.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;


@Component
public class TokenCheckFilter implements GlobalFilter, Ordered {
    /**
     * 指定好放行的路徑,白名單
     */
    public static final List<String> ALLOW_URL= Arrays.asList("/doLogin","/myUrl");

    @Autowired
    private StringRedisTemplate redisTemplate;
    /**
     * 和前端約定好 一般放在請求頭類里面一般key為 Authorization value bearer token
     * 1.拿到請求url
     * 2.判斷放行
     * 3.拿到請求頭
     * 4.拿到token
     * 5.校驗(yàn)
     * 6.放行/攔截
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        if (ALLOW_URL.contains(path)) {
            return chain.filter(exchange);
        }
        //檢查
        List<String> authorization = request.getHeaders().get("Authorization");
        if (!CollectionUtils.isEmpty(authorization)){
            String token = authorization.get(0);
            if(StringUtils.hasText(token)){
                //約定好的有前綴的bearer token
                String realToken = token.replaceFirst("bearer ", "");
                if (StringUtils.hasText(realToken)&&redisTemplate.hasKey(realToken)){
                    return chain.filter(exchange);
                }
            }
        }
        //攔截
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().set("content-type","application/json;charset=utf-8");
        //組裝業(yè)務(wù)返回值
        HashMap<String ,Object> map=new HashMap<>(4);
        map.put("code", HttpStatus.UNAUTHORIZED);
        map.put("msg","未授權(quán)");
        ObjectMapper objectMapper=new ObjectMapper();
        //把一個(gè)map轉(zhuǎn)換為字節(jié)
        byte[] bytes = new byte[0];
        try {
            bytes = objectMapper.writeValueAsBytes(map);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        //通過buffer工廠將字節(jié)數(shù)組包裝成一個(gè)數(shù)據(jù)報(bào)
        DataBuffer wrap = response.bufferFactory().wrap(bytes);
        return response.writeWith(Mono.just(wrap));

    }

    @Override
    public int getOrder() {
        return 0;
    }
}

login-service服務(wù)

pom.xml文件

在pom文件中新增redis的依賴

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

注意博主是在本機(jī)安裝的redis所以不需要在服務(wù)中添加對應(yīng)的redis配置。

LoginController類

在LoginController類中新增doLogin方法

@Autowired
    public StringRedisTemplate redisTemplate;

    @PostMapping("doLogin")
    public String doLogin(@RequestBody User user){
        //token
        String token= UUID.randomUUID().toString();
        //存起來
        redisTemplate.opsForValue().set(token,user.toString(), Duration.ofSeconds(7200));
        return token;
    }

訪問測試

http://localhost:81/doLogin

由于在gateway將該/doLogin放入了白名單,所以該請求不會(huì)進(jìn)行token校驗(yàn),發(fā)送請求成功之后會(huì)返回token
【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway
訪問http://localhost:81/teach,并在請求頭中添加token,最后可以看到請求訪問成功。

【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

如果我們不在請求頭中添加對應(yīng)的token或者token為錯(cuò)誤token,那么gateway會(huì)將請求進(jìn)行攔截。

【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān),微服務(wù),spring cloud,java,gateway

總結(jié)

  1. gateway在微服務(wù)中起到了很重要的作用,作為項(xiàng)目請求的統(tǒng)一入口。
  2. gateway也體現(xiàn)了我們軟件設(shè)計(jì)的復(fù)用思想,可以統(tǒng)一進(jìn)行跨域處理,進(jìn)行token校驗(yàn)。
  3. gateway比較重要的一塊是關(guān)于他的過濾器,通過實(shí)現(xiàn)過濾器的接口,可以自定義過濾器,提供了很強(qiáng)大的可擴(kuò)展支持

升華

通過學(xué)習(xí)gateway不光是學(xué)習(xí)gateway更重要的是學(xué)習(xí)軟件設(shè)計(jì)思想。文章來源地址http://www.zghlxwxcb.cn/news/detail-653822.html

到了這里,關(guān)于【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • springboot整合spring cloud gateway搭建網(wǎng)關(guān)服務(wù)

    springboot整合spring cloud gateway搭建網(wǎng)關(guān)服務(wù)

    spring cloud netflix zuul、spring cloud gateway是最常見的微服務(wù)網(wǎng)關(guān),通過網(wǎng)關(guān),我們可以在請求到達(dá)后端指定服務(wù)之前/后端服務(wù)處理完業(yè)務(wù)響應(yīng)數(shù)據(jù)之后對響應(yīng)進(jìn)行對請求/響應(yīng)進(jìn)行處理。 比如常見的參數(shù)校驗(yàn)、接口鑒權(quán)等等,在后端服務(wù)的攔截器和過濾器能做的事在網(wǎng)關(guān)都可以做

    2024年02月07日
    瀏覽(25)
  • Eureka上集成Spring Cloud 微服務(wù)網(wǎng)關(guān) gateway

    Eureka上集成Spring Cloud 微服務(wù)網(wǎng)關(guān) gateway

    第一章 Java線程池技術(shù)應(yīng)用 第二章 CountDownLatch和Semaphone的應(yīng)用 第三章 Spring Cloud 簡介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 第七章 Spring Cloud 之 GateWay API 網(wǎng)關(guān)是一個(gè)搭建在客戶端和微服務(wù)之間的服務(wù),我們可以在 API 網(wǎng)關(guān)中

    2024年02月08日
    瀏覽(23)
  • 【springcloud 微服務(wù)】Spring Cloud 微服務(wù)網(wǎng)關(guān)Gateway使用詳解

    目錄 一、微服務(wù)網(wǎng)關(guān)簡介 1.1 網(wǎng)關(guān)的作用 1.2 常用網(wǎng)關(guān) 1.2.1 傳統(tǒng)網(wǎng)關(guān) 1.2.2?云原生網(wǎng)關(guān)

    2023年04月16日
    瀏覽(30)
  • Spring Cloud Gateway - 新一代微服務(wù)API網(wǎng)關(guān)

    Spring Cloud Gateway - 新一代微服務(wù)API網(wǎng)關(guān)

    如果沒有網(wǎng)關(guān),難道不行嗎?功能上是可以的,我們直接調(diào)用提供的接口就可以了。那為什么還需要網(wǎng)關(guān)? 因?yàn)榫W(wǎng)關(guān)的作用不僅僅是轉(zhuǎn)發(fā)請求而已。我們可以試想一下,如果需要做一個(gè)請求認(rèn)證功能,我們可以接入到 API 服務(wù)中。但是倘若后續(xù)又有服務(wù)需要接入,我們又需要

    2024年02月16日
    瀏覽(27)
  • Spring Cloud Gateway:打造可擴(kuò)展的微服務(wù)網(wǎng)關(guān)

    Spring Cloud Gateway:打造可擴(kuò)展的微服務(wù)網(wǎng)關(guān)

    ??歡迎來到架構(gòu)設(shè)計(jì)專欄~Spring Cloud Gateway:打造可擴(kuò)展的微服務(wù)網(wǎng)關(guān) ☆* o(≧▽≦)o *☆嗨~我是IT·陳寒?? ?博客主頁:IT·陳寒的博客 ??該系列文章專欄:架構(gòu)設(shè)計(jì) ??其他專欄:Java學(xué)習(xí)路線 Java面試技巧 Java實(shí)戰(zhàn)項(xiàng)目 AIGC人工智能 數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí) ??文章作者技術(shù)和水平有限

    2024年02月08日
    瀏覽(91)
  • Spring Cloud Gateway 服務(wù)網(wǎng)關(guān)的部署與使用詳細(xì)介紹

    Spring Cloud Gateway 服務(wù)網(wǎng)關(guān)的部署與使用詳細(xì)介紹

    1、什么是服務(wù)網(wǎng)關(guān): ????????傳統(tǒng)的單體架構(gòu)中只需要開放一個(gè)服務(wù)給客戶端調(diào)用,但是微服務(wù)架構(gòu)中是將一個(gè)系統(tǒng)拆分成多個(gè)微服務(wù),如果沒有網(wǎng)關(guān),客戶端只能在本地記錄每個(gè)微服務(wù)的調(diào)用地址,當(dāng)需要調(diào)用的微服務(wù)數(shù)量很多時(shí),它需要了解每個(gè)服務(wù)的接口,這個(gè)工

    2024年02月02日
    瀏覽(26)
  • Spring Cloud 微服務(wù)中 gateway 網(wǎng)關(guān)如何設(shè)置健康檢測端點(diǎn)

    Spring Cloud 微服務(wù)中 gateway 網(wǎng)關(guān)如何設(shè)置健康檢測端點(diǎn)

    主要是為了讓 k8s 識(shí)別到網(wǎng)關(guān)項(xiàng)目已經(jīng)就緒,但是又不想在里面通過 Controller 實(shí)現(xiàn)。因?yàn)樵?Controller 中這樣做并不是最佳實(shí)踐,因?yàn)?Gateway 的設(shè)計(jì)初衷是專注于路由和過濾,而不是業(yè)務(wù)邏輯的處理。 在 Gateway 中配置健康檢查端點(diǎn)可以通過以下方式進(jìn)行(可根據(jù)實(shí)際需求進(jìn)行擴(kuò)

    2024年01月17日
    瀏覽(24)
  • Spring Cloud Alibaba全家桶(十)——微服務(wù)網(wǎng)關(guān)Gateway組件

    Spring Cloud Alibaba全家桶(十)——微服務(wù)網(wǎng)關(guān)Gateway組件

    本文小新為大家?guī)?微服務(wù)網(wǎng)關(guān)Gateway組件 相關(guān)知識(shí),具體內(nèi)容包括 微服務(wù)網(wǎng)關(guān)Gateway組件 (包括: Gateway核心概念 , Gateway工作原理 ), Spring Cloud Gateway環(huán)境搭建 , 路由斷言工廠(Route Predicate Factories)配置 , 過濾器工廠( Gateway Filter Factories)配置 , 全局過濾器(Glob

    2023年04月08日
    瀏覽(21)
  • 【使用Spring Cloud Gateway構(gòu)建微服務(wù)網(wǎng)關(guān)】—— 每天一點(diǎn)小知識(shí)

    【使用Spring Cloud Gateway構(gòu)建微服務(wù)網(wǎng)關(guān)】—— 每天一點(diǎn)小知識(shí)

    · ??????????????????????????????????????????????????????????????????????? ?? 使用 S p r i n g C l o u d G a t e w a y 構(gòu)建微服務(wù)網(wǎng)關(guān) color{#FF1493}{使用Spring Cloud Gateway構(gòu)建微服務(wù)網(wǎng)關(guān)} 使用 Sp r in g Cl o u d G a t e w a y 構(gòu)建微服務(wù)網(wǎng)關(guān) ?? ???????

    2024年02月10日
    瀏覽(42)
  • 【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān)

    【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān)

    【Spring Cloud一】微服務(wù)基本知識(shí) 【Spring Cloud 三】Eureka服務(wù)注冊與服務(wù)發(fā)現(xiàn) 【Spring Cloud 四】Ribbon負(fù)載均衡 【Spring Cloud 五】OpenFeign服務(wù)調(diào)用 【Spring Cloud 六】Hystrix熔斷 【Spring Cloud 七】Sleuth+Zipkin 鏈路追蹤 在項(xiàng)目中是使用了Gateway做統(tǒng)一的請求的入口,以及統(tǒng)一的跨域處理以及

    2024年02月12日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包