diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/pom.xml b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/pom.xml
new file mode 100644
index 00000000..860c0774
--- /dev/null
+++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/pom.xml
@@ -0,0 +1,60 @@
+
+
+
+ labx-08
+ cn.iocoder.springboot.labs
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ labx-08-sc-gateway-demo05-custom-gateway-filter
+
+
+ 1.8
+ 1.8
+ 2.2.4.RELEASE
+ Hoxton.SR1
+ 2.2.0.RELEASE
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ ${spring.boot.version}
+ pom
+ import
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring.cloud.version}
+ pom
+ import
+
+
+ com.alibaba.cloud
+ spring-cloud-alibaba-dependencies
+ ${spring.cloud.alibaba.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-gateway
+
+
+
+
diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java
new file mode 100644
index 00000000..f9575ef3
--- /dev/null
+++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java
@@ -0,0 +1,13 @@
+package cn.iocoder.springcloud.labx08.gatewaydemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class GatewayApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(GatewayApplication.class, args);
+ }
+
+}
diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/AuthGatewayFilterFactory.java b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/AuthGatewayFilterFactory.java
new file mode 100644
index 00000000..f54c3e0b
--- /dev/null
+++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/AuthGatewayFilterFactory.java
@@ -0,0 +1,98 @@
+package cn.iocoder.springcloud.labx08.gatewaydemo.filter;
+
+import org.springframework.cloud.gateway.filter.GatewayFilter;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpHeaders;
+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.StringUtils;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory {
+
+ public AuthGatewayFilterFactory() {
+ super(AuthGatewayFilterFactory.Config.class);
+ }
+
+ @Override
+ public GatewayFilter apply(Config config) {
+ // token 和 userId 的映射
+ Map tokenMap = new HashMap<>();
+ tokenMap.put("yunai", 1);
+
+ // 创建 GatewayFilter 对象
+ return new GatewayFilter() {
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ // 获得 token
+ ServerHttpRequest request = exchange.getRequest();
+ HttpHeaders headers = request.getHeaders();
+ String token = headers.getFirst(config.getTokenHeaderName());
+
+ // 如果没有 token,则不进行认证。因为可能是无需认证的 API 接口
+ if (!StringUtils.hasText(token)) {
+ return chain.filter(exchange);
+ }
+
+ // 进行认证
+ ServerHttpResponse response = exchange.getResponse();
+ Integer userId = tokenMap.get(token);
+
+ // 通过 token 获取不到 userId,说明认证不通过
+ if (userId == null) {
+ // 响应 401 状态码
+ response.setStatusCode(HttpStatus.UNAUTHORIZED);
+ // 响应提示
+ DataBuffer buffer = exchange.getResponse().bufferFactory().wrap("认证不通过".getBytes());
+ return response.writeWith(Flux.just(buffer));
+ }
+
+ // 认证通过,将 userId 添加到 Header 中
+ request = request.mutate().header(config.getUserIdHeaderName(), String.valueOf(userId))
+ .build();
+ return chain.filter(exchange.mutate().request(request).build());
+ }
+
+ };
+ }
+
+ public static class Config {
+
+ private static final String DEFAULT_TOKEN_HEADER_NAME = "token";
+ private static final String DEFAULT_HEADER_NAME = "user-id";
+
+ private String tokenHeaderName = DEFAULT_TOKEN_HEADER_NAME;
+ private String userIdHeaderName = DEFAULT_HEADER_NAME;
+
+ public String getTokenHeaderName() {
+ return tokenHeaderName;
+ }
+
+ public String getUserIdHeaderName() {
+ return userIdHeaderName;
+ }
+
+ public Config setTokenHeaderName(String tokenHeaderName) {
+ this.tokenHeaderName = tokenHeaderName;
+ return this;
+ }
+
+ public Config setUserIdHeaderName(String userIdHeaderName) {
+ this.userIdHeaderName = userIdHeaderName;
+ return this;
+ }
+
+ }
+
+}
diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/resources/application.yaml
new file mode 100644
index 00000000..f9d50ef0
--- /dev/null
+++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/resources/application.yaml
@@ -0,0 +1,29 @@
+server:
+ port: 8888
+
+spring:
+ application:
+ name: gateway-application
+
+ cloud:
+ # Spring Cloud Gateway 配置项,对应 GatewayProperties 类
+ gateway:
+ # 路由配置项,对应 RouteDefinition 数组
+ routes:
+ - id: yudaoyuanma # 路由的编号
+ uri: http://www.iocoder.cn # 路由到的目标地址
+ predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
+ - Path=/blog
+ filters:
+ - StripPrefix=1
+ - id: oschina # 路由的编号
+ uri: https://www.oschina.net # 路由的目标地址
+ predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
+ - Path=/oschina
+ filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组
+ - StripPrefix=1
+ # 默认过滤器,对应 FilterDefinition 数组
+ default-filters:
+ - name: Auth
+ args:
+ token-header-name: access-token
diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/target/classes/application.yaml b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/target/classes/application.yaml
new file mode 100644
index 00000000..f9d50ef0
--- /dev/null
+++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/target/classes/application.yaml
@@ -0,0 +1,29 @@
+server:
+ port: 8888
+
+spring:
+ application:
+ name: gateway-application
+
+ cloud:
+ # Spring Cloud Gateway 配置项,对应 GatewayProperties 类
+ gateway:
+ # 路由配置项,对应 RouteDefinition 数组
+ routes:
+ - id: yudaoyuanma # 路由的编号
+ uri: http://www.iocoder.cn # 路由到的目标地址
+ predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
+ - Path=/blog
+ filters:
+ - StripPrefix=1
+ - id: oschina # 路由的编号
+ uri: https://www.oschina.net # 路由的目标地址
+ predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
+ - Path=/oschina
+ filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组
+ - StripPrefix=1
+ # 默认过滤器,对应 FilterDefinition 数组
+ default-filters:
+ - name: Auth
+ args:
+ token-header-name: access-token
diff --git a/labx-08/pom.xml b/labx-08/pom.xml
index aff50d4c..0dca5840 100644
--- a/labx-08/pom.xml
+++ b/labx-08/pom.xml
@@ -20,6 +20,8 @@
labx-08-sc-gateway-demo04
+ labx-08-sc-gateway-demo05-custom-gateway-filter
+
labx-08-sc-user-service