【网关系统框架】脚手架项目
概述
【网关系统框架】项目是一个脚手架项目,来帮助开发同事快速搭建一个完整结构的网关层项目,开发者在生成的项目基础上进行开发即可,以提高开发效率和代码质量。
【网关系统框架】项目功能主要体现在:
- 不必从零开始搭建初始项目,提高开发效率
- 路由功能
- token认证 和 URL鉴权
- 限流功能
- 路径重写
- 跨域配置
- 通过 Feign 调用下游系统接口
路由功能
1、基于 Path 路径的路由断言
PathRoutePredicateFactory
: 接收一个正则列表,根据路径进行匹配,如果满足规则,则转发到配置的 uri 地址
spring:
cloud:
gateway:
routes:
- id: path_route
# 路由跳转地址
uri: https://www.csdn.net
predicates:
- Path=/blog/{segment}, /edu/**
如上:/blog/1
、/blog/java
、/edu/php
等请求都将被匹配。
URI 模板变量 (如上例中的 segment ) 将以 Map 键值的方式保存于 ServerWebExchange.getAttributes()
中,
可以在 GatewayFilterFactory
中使用。
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
String segment = uriVariables.get("segment");
2、基于 Query 请求参数的路由断言
QueryRoutePredicateFactory
: 接收两个参数,一个请求参数(必传)和一个正则表达式(可选),判断请求参数是否具有给定名称且值与正则表达式匹配。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://www.csdn.net
predicates:
# - Query=blog
- Query=blog, java.*
如上,- Query=blog
会匹配包含请求参数 blog 的请求;
- Query=blog, java.*
会匹配请求中包含参数 blog,并且值以 java 开头(java / java1 / java123 等)的请求。
3、基于 Method 请求方式的路由断言
MethodRoutePredicateFactory
: 匹配一个或多个 HTTP 请求方式(GET / POST / PUT / DELETE / HEAD 等)
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://www.csdn.net
predicates:
- Method: GET,POST
所有 GET 请求和 POST 请求都将被路由
4、基于 Datetime 日期时间的路由断言
此类型的断言根据时间做判断,主要有三个:
AfterRoutePredicateFactory
: 接收一个日期参数,判断请求日期是否晚于指定日期BeforeRoutePredicateFactory
: 接收一个日期参数,判断请求日期是否早于指定日期BetweenRoutePredicateFactory
: 接收两个日期参数,判断请求日期是否在指定时间段内
spring:
cloud:
gateway:
routes:
- id: datetime_route
uri: https://www.csdn.net
predicates:
# - After=2021-08-30T23:59:59.789+08:00[Asia/Shanghai]
# - Before=2021-09-30T23:59:59.789+08:00[Asia/Shanghai]
- Between=2021-08-30T23:59:59.789+08:00[Asia/Shanghai], 2021-09-30T23:59:59.789+08:00[Asia/Shanghai]
5、基于 Weight 权重的路由断言
WeightRoutePredicateFactory
: 接收一个[组名, 权重],然后对同一个组内的路由按照权重转发
spring:
cloud:
gateway:
routes:
- id: weight_route1
uri: https://www.csdn.net
predicates:
- Path=/blog/**
# blogGroup 是组名, 90 是权重
- Weight=blogGroup, 90
- id: weight_route2
uri: https://www.cnblogs.com
predicates:
- Path=/blog/**
# blogGroup 是组名, 10 是权重
- Weight=blogGroup, 10
此断言可用于实现灰度发布等功能。
6、基于 Header 头信息的路由断言
HeaderRoutePredicateFactory
:接收两个参数,header名称和一个正则表达式。 判断请求头信息中是否具有给定名称且值与正则表达式匹配。
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://www.csdn.net
predicates:
- Header=X-Request-Id, BLOG
匹配请求头中,参数名称为 X-Request-Id, 且值为 BLOG 的请求。
7、基于 Cookie 的路由断言
CookieRoutePredicateFactory
:接收两个参数,cookie 名称和一个正则表达式。 判断请求 cookie 是否具有给定名称且值与正则表达式匹配。
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://www.csdn.net
predicates:
- Cookie=UserName, 123456
8、基于 Host 的路由断言
HostRoutePredicateFactory
:接收一个正则域名列表。判断请求的 Host 是否满足匹配规则。
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://www.csdn.net
predicates:
- Host=**.order.haier.com, **.goods.haier.com
9、基于 RemoteAddr 远程地址的路由断言
RemoteAddrRoutePredicateFactory
:接收一个IP地址(格式为 ip/子网掩码)列表,判断请求主机地址是否在地址段中。
spring:
cloud:
gateway:
routes:
- id: remoteAddr_route
uri: https://www.csdn.net
predicates:
- RemoteAddr=192.168.1.1/24, 192.168.0.100
如上,192.168.1.1 是IP地址,24是子网掩码,如果没有写子网掩码,默认为32(255.255.255.255)
token认证 和 URL鉴权
白名单
配置到白名单的 url,不需要进行token认证 和 URL鉴权。
示例如下:
jwt:
# 无需进行 token 校验的请求路径列表,请求支持通配符和RESTFUL规范
# 示例:
# 1、/admin/sys/login (可以匹配 /admin/sys/login 和 /admin/sys/login )
# 2、/admin/sys/login/*(可以匹配 /admin/sys/login/ 、 /admin/sys/login/1 和 /admin/sys/login/1/)
# 3、/admin/sys/login/**(可以匹配 /admin/sys/login/ 、 /admin/sys/login/1 、 /admin/sys/login/1/ 和 /admin/sys/login/1/1 等)
# 4、/admin/sys/login/? (可以匹配 /admin/sys/login/1 和 /admin/sys/login/1/)
# 5、/admin/sys/login::POST(只能匹配 POST 请求方式)
# 6、/admin/sys/login/?::POST(匹配 POST 请求方式的 /admin/sys/login/1 和 /admin/sys/login/1/)
# 7、......
allowedList:
- /login
- /limit/**
- /demo/allow/*::POST # 如果需要限制请求类型,则在请求地址后边添加 [::请求类型]
token 认证
对不在白名单中的请求,会先进行 token 校验。token 在 header 中进行传输,相关配置见 JwtTokenConfig。
jwt:
secret: xxxxxxxx #JWT加解密使用的密钥
expiration: 1800 #JWT的超期限时间(60 * 30),单位s
token 续期
当 token 校验通过后,会尝试重新生成 token,如果重新生成 token 成功,则会将新 token 保存到 response header 中。
生成逻辑为:原 token 没有过期,并且剩余有效时间小于总有效时间的一半时,会生成新 token。
设置全局 header 信息
网关层可以将下游微服务系统使用到的通用信息保存到 header 中,如下:
// 将下游系统需要使用的属性,设置到 header 中
// 将下游系统需要使用的属性,设置到 header 中
ServerHttpRequest newRequest = exchange.getRequest().mutate()
.header(JwtTokenConfig.HEADER_TOKEN_KEY, "")
.header(GlobalHeaderConstant.USER_NAME_KEY, userName)
.header(Request.USER_HEADER, UserJsonUtils.serialize(jwtTokenUtil.getUserFromToken(token)))
.build();
log.info("转发后的header信息[{}]",newRequest.getHeaders());
如需设置多个信息,可以使用 exchange.getRequest().mutate().headers()
进行保存设置
限流功能
# 限流示例
- id: limit_route
uri: http://localhost:8080
predicates:
- Path=/limit/test
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
# 使用SpEL按名称引用bean
key-resolver: "#{@ipKeyResolver}"
# 令牌桶填充平均速率 (每秒最大访问次数)
redis-rate-limiter.replenishRate: 1
# 令牌桶上限
redis-rate-limiter.burstCapacity: 2
RequestRateLimiter 是限流过滤器,该过滤器需要配置三个参数:
- burstCapacity,令牌桶总容量。
- replenishRate,令牌桶每秒填充平均速率。
- key-resolver,用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。
稳定速率是通过在 replenishRate 和 burstCapacity 中设置相同的值来实现的。可通过设置 burstCapacity 高于 replenishRate 来允许临时突发流量。
路径重写
StripPrefix 去掉请求路径的最前面 n个部分
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: http://localhost:8080
predicates:
- Path=/name/**
filters:
- StripPrefix=2
请求 /name/blue/red 会转发到 /red
PrefixPath 在请求路径前添加前缀
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://localhost:8080
filters:
- PrefixPath=/mypath
访问/test 的请求被发送到 http://localhost:8080/mypath/test
RedirectTo 重定向,配置包含重定向的返回码和地址
spring:
cloud:
gateway:
routes:
- id: redirectTo_route
uri: http://localhost:8080
filters:
- RedirectTo=302, http://localhost:8081
RewritePath 改写路径
spring:
cloud:
gateway:
routes:
- id: rewrite_filter
uri: http://localhost:8080
predicates:
- Path=/test/**
filters:
- RewritePath=/where(?<segment>/?.*), /test(?<segment>/?.*)
/where/... 改成 /test/...
SetPath 设置请求路径,与RewritePath类似
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: http://localhost:8080
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
如 /red/blue 的请求被转发到 /blue
SetRequestHeader 设置请求头信息
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: http://localhost:8080
filters:
- SetRequestHeader=X-Request-Red, Blue
RemoveRequestHeader 去掉某个请求头信息
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: http://localhost:8080
filters:
- RemoveRequestHeader=X-Request-Foo
去掉请求头信息 X-Request-Foo
RemoveRequestParameter 去掉某个请求参数信息
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: http://localhost:8080
filters:
- RemoveRequestParameter=userName
Default-filters 对所有请求添加过滤器
spring:
cloud:
gateway:
default-filters:
- PrefixPath=/test
跨域配置
# 跨域配置
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOriginPatterns: '*'
allowedMethods: '*'
allowedHeaders: '*'
allowCredentials: true
通过 Feign 调用下游系统接口
在启动类中设置FeignClient路径,如:
@EnableFeignClients(basePackages = {"com.haier.gdp.rbac.feign.client"})
pom 文件中引入下游系统的 api jar包,如:
<dependency>
<groupId>com.haier.rdtp</groupId>
<artifactId>product-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
在 yml 配置文件中配置 feign url,如
feign:
client:
config:
default:
connectTimeout: 3000
readTimeout: 10000
loggerLevel: full
product-api:
url: http://localhost:8081
注意:此路径结构需要查看调用的 api jar 来确认,如下:
@FeignClient(url = "${feign.client.config.product-api.url}", name = "product-api")
注入使用,如下:
@Resource
private SysLoginClient sysLoginClient;
// 调后台系统接口进行登录验证
GlobalResponse<SysLoginRespDTO> loginResp = sysLoginClient.login(loginDTO);
关于token的生产
本地开发时候,可以通过token访问网关转发到各个微服务,也可以直接连接微服务信息。关于token的生成或者是微服务中用户信息的header生成请参见 com.haier.cosmo.im.platform.gateway.GatewayApplicationTests.contextLoads
User user = new User().setUserId("12345")
.setLoginName("21012273")
.setUserType(UserType.HAIER)
.setUserName("刘志龙")
.setPhone("15853247703")
.setEmail("[email protected]");
// 序列化的用户信息 放在 header system_user_info 直接调用微服务
System.out.println( UserJsonUtils.serialize(user));;
System.out.println(jwtTokenUtil.generateToken(user, Arrays.asList()));
标签:请求,admin,配置,uri,login,gateway,cloud
From: https://www.cnblogs.com/shareToAll/p/18053329