From e58deef8eef751e170dd095c7e65db8996a563b1 Mon Sep 17 00:00:00 2001 From: YunaiV <> Date: Fri, 28 Feb 2020 18:45:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20spring=20cloud=20gateway?= =?UTF-8?q?=20=E7=BD=91=E5=85=B3=E7=9A=84=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pom.xml | 60 ++++++++++++ .../gatewaydemo/GatewayApplication.java | 13 +++ .../filter/AuthGatewayFilterFactory.java | 98 +++++++++++++++++++ .../src/main/resources/application.yaml | 29 ++++++ .../target/classes/application.yaml | 29 ++++++ labx-08/pom.xml | 2 + 6 files changed, 231 insertions(+) create mode 100644 labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/pom.xml create mode 100644 labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java create mode 100644 labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/AuthGatewayFilterFactory.java create mode 100644 labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/resources/application.yaml create mode 100644 labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/target/classes/application.yaml 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