动态网关
基于 nacos 动态网关
pom 依赖
xml
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.github.itdachen.framework</groupId>
<artifactId>fly-runner</artifactId>
</dependency>
<!-- 网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 动态网关 -->
<dependency>
<groupId>com.github.itdachen.framework.cloud</groupId>
<artifactId>fly-cloud-gateway-dynamic-routes</artifactId>
</dependency>
<!-- openfeign 封装, RestTemplate 封装 -->
<dependency>
<groupId>com.github.itdachen.framework.cloud</groupId>
<artifactId>fly-cloud-openfeign</artifactId>
</dependency>
<!-- 服务注册与发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- 健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>配置文件
编写配置文件 'bootstrap.yml'
yaml
spring:
profiles:
active: dev
# 暴露 SpringBoot Actuator Endpoint
management:
endpoints:
web:
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 *, 可以开放所有端点
endpoint:
health:
show-details: ALWAYS编写配置文件 'bootstrap-dev.yml'
yaml
# 端口配置
server:
port: 8080
servlet:
context-path: /api
# 认证中心配置
fly:
cloud:
auth:
token:
type: RSA
app:
service-id: auth
app-id: ${spring.application.name}
app-secret: 123456
## 网关配置
gateway:
### 动态获取 nacos 中的路由配置
routes:
username: nacos
password: nacos
serverAddr: 127.0.0.1:8848
namespace: b6783835-a27f-4ec3-b9ee-05bfa917e812
dataId: GATEWAY_ROUTES
group: GATEWAY_ROUTES
### 配置网关不拦截路径前缀, 不需要权限认证等
ignore:
matchers:
- /auth/oauth/access_token
- /auth/oauth/token
- /api/actuator
- /actuator
- /admin/open/dict
- /oss
- /oss/upload
- /flexible/login
- /flexible/authentication/form
spring:
application:
name: gateway
main:
allow-circular-references: true
allow-bean-definition-overriding: true
web-application-type: REACTIVE
servlet:
# 文件上传
multipart:
max-file-size: 1024MB
max-request-size: 1024MB
cloud:
nacos:
username: nacos
password: nacos
server-addr: 127.0.0.1:8848
discovery:
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
username: nacos
password: nacos
server-addr: 127.0.0.1:8848
namespace: 07656b3c-bb69-470a-a942-6ae27b5287cb
group: FLY_GROUP
metadata:
management:
context-path: ${server.servlet.context-path}/actuator
loadbalancer:
cache:
ttl: 5s
# 重试策略
retry:
maxRetriesOnSameServiceInstance: 0
maxRetriesOnNextServiceInstance: 0
clients:
service-product:
retry:
maxRetriesOnSameServiceInstance: 0
maxRetriesOnNextServiceInstance: 0
gateway:
discovery:
locator:
enabled: true
#服务名小写
lower-case-service-id: true
globalcors:
cors-configurations: # 跨域配置
'[/**]': # 匹配所有路径
allowed-origins: # 允许的域名
- "http://localhost:7080"
allowed-headers: "*" # 允许的请求头
allowed-methods: "*" # 允许的方法
allow-credentials: true # 是否携带cookie
httpclient:
pool:
max-connections: 500
max-idle-time: 10000
feign:
httpclient:
enabled: true
max-connections: 200
max-connections-per-route: 50配置动态路由
创建配置文件命令空间
nacos 创建命名空间, 命名空间ID为: 07656b3c-bb69-470a-a942-6ae27b5287cb
配置动态路由

- 点击配置列表
- 选择命名空间
- 点击新增按钮填写配置信息
填写配置信息
- 新建配置文件,
Data ID和Group填GATEWAY_ROUTES - 配置格式选择
JSON - 配置文件如下:
json
[
{
"id": "gateway",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/api/actuator/**"
}
}
],
"uri": "lb://gateway",
"filters": [
{
"name": "StripPrefix",
"args": {
"parts": "1"
}
}
]
},
{
"id": "auth",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/api/auth/**"
}
}
],
"uri": "lb://auth",
"filters": [
{
"name": "StripPrefix",
"args": {
"parts": "1"
}
}
]
},
{
"id": "auth-client-demo",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/api/auth-client-demo/**"
}
}
],
"uri": "lb://auth-client-demo",
"filters": [
{
"name": "StripPrefix",
"args": {
"parts": "1"
}
}
]
}
]路由配置
动态配置路由如下:
json
{
"id": "auth",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/api/auth/**"
}
}
],
"uri": "lb://auth",
"filters": [
{
"name": "StripPrefix",
"args": {
"parts": "1"
}
}
]
}- id: 路由唯一标识
- predicates: 路由断言
- uri: 目标服务地址
- filters: 过滤器
- order: 路由匹配顺序,数字越小优先级越高
predicates 断言
json
{
"name": "Path",
"args": {
"pattern": "/api/auth/**"
}
}- Path: 断言,路径相匹配的进行路由
- pattern: 匹配路径
filters 过滤器
json
{
"name": "StripPrefix",
"args": {
"parts": "1"
}
}- StripPrefix: 转发时去除前缀1层路径(/api/)
创建全局过滤器
创建 GatewayGlobalFilter 全局过滤器
@Configuration
@SuppressWarnings("all")
public class GatewayGlobalFilter implements GlobalFilter {
private static final Logger logger = LoggerFactory.getLogger(GatewayGlobalFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange webExchange, GatewayFilterChain filterChain) {
ServerHttpRequest request = webExchange.getRequest();
String path = request.getURI().getPath();
logger.info("path ==> " + path);
return filterChain.filter(webExchange);
}
}启动类
@EnableAsync
@RefreshScope
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients({"com.github.itdachen"})
@ComponentScan(basePackages = {"com.github.itdachen"})
public class GatewayBootstrap {
public static void main(String[] args) {
SpringBootBootstrap.run(GatewayBootstrap.class);
}
}启动项目
启动项目, 控制台打印路由信息 
测试
创建 http 文件, 通过网关理由转发进行登录和获取用户信息
### 账号密码登录
POST http://localhost:8080/api/auth/oauth/jwt/token
Content-Type: application/json
{
"username": "admin",
"password": "123456"
}
### 获取登录用户(auth)
GET http://localhost:8080/api/auth/current/user/details
Accept: application/json
Verified-Ticket: verifiedTicket # 校验
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzUxMiJ9.eyJuaWNrTmFtZSI6IueOi-Wkp-WuuCIsInVzZXJUeXBlIjoiNCIsInVzZXJJZCI6IjEiLCJhY2NvdW50IjoiYWRtaW4iLCJpc3MiOiJjb20uZ2l0aHViLml0ZGFjaGVuIiwiaWF0IjoxNjkzMDYwODU0LCJleHAiOjE2OTMwNzg4NTR9.LXYbIG9Jl3_6I_-6-XqNKLTDX3WkltIkWkPIbioQBxTHHFikEhWws8qxyWTGjoZiyRMYW4wuhf3nyLEJeDFEgUGYgfRwXhIQSECSoJCEVF-nCdFXTbM2_isGW-Q1SjqCt0Yp2BT34Mbz5tKyCTgzVBGDW3_BIsJquTmHmAkR9Wev0YcSm4vmaUeIbJVYHrQUQVRjEPRAVQmv3ukrVQirxE8TBGGb7vm9rs-9xALzEmS-RTEO4suhnSZpXTy8qtIdUZeWiq2Hp2GNu4B4dfMht88jHUXJ-oufgLowqnJxH8qzwFHvsoFdxP1pBXqzjmEDWA3EiWhJEfLIVX1TqyJiWDkQJFUFAXlUtt3Dy2nSgP3gbMdzf3pV-nFPhdrUbHOd9yc_I2oXsRpE8bcsOwCLHyvOM5-Rw2z82cSSPApZPB66tu_FK_PdCjtS2L2yHe4L0JuTZOz4fFKXE0Q2hqL1ZLxqkeDumOIHvUldU0PUSlfFkWRpU2c_4wjZOPy7X7G_erwrWYorV5auIYTajh5gawEieIJp5AQOYrRdLgSNUEZf_M67hzrsnjHAhjHwKobEEP-rlZDKhJTIyEM1KaFZNg1bvXeAarUGDyBCwzNXetno8b2MwMb5wj7x2qSxL1fOBqPZWA-SbGHtWu44W4BSbtmy4F6Rhae21myZ_OFxaWM
### 获取登录用户(auth-client-demo)
GET http://localhost:8080/api/auth-client-demo/current/user/details
Accept: application/json
Verified-Ticket: verifiedTicket
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzUxMiJ9.eyJuaWNrTmFtZSI6IueOi-Wkp-WuuCIsInVzZXJUeXBlIjoiNCIsInVzZXJJZCI6IjEiLCJhY2NvdW50IjoiYWRtaW4iLCJpc3MiOiJjb20uZ2l0aHViLml0ZGFjaGVuIiwiaWF0IjoxNjkzMDYwODU0LCJleHAiOjE2OTMwNzg4NTR9.LXYbIG9Jl3_6I_-6-XqNKLTDX3WkltIkWkPIbioQBxTHHFikEhWws8qxyWTGjoZiyRMYW4wuhf3nyLEJeDFEgUGYgfRwXhIQSECSoJCEVF-nCdFXTbM2_isGW-Q1SjqCt0Yp2BT34Mbz5tKyCTgzVBGDW3_BIsJquTmHmAkR9Wev0YcSm4vmaUeIbJVYHrQUQVRjEPRAVQmv3ukrVQirxE8TBGGb7vm9rs-9xALzEmS-RTEO4suhnSZpXTy8qtIdUZeWiq2Hp2GNu4B4dfMht88jHUXJ-oufgLowqnJxH8qzwFHvsoFdxP1pBXqzjmEDWA3EiWhJEfLIVX1TqyJiWDkQJFUFAXlUtt3Dy2nSgP3gbMdzf3pV-nFPhdrUbHOd9yc_I2oXsRpE8bcsOwCLHyvOM5-Rw2z82cSSPApZPB66tu_FK_PdCjtS2L2yHe4L0JuTZOz4fFKXE0Q2hqL1ZLxqkeDumOIHvUldU0PUSlfFkWRpU2c_4wjZOPy7X7G_erwrWYorV5auIYTajh5gawEieIJp5AQOYrRdLgSNUEZf_M67hzrsnjHAhjHwKobEEP-rlZDKhJTIyEM1KaFZNg1bvXeAarUGDyBCwzNXetno8b2MwMb5wj7x2qSxL1fOBqPZWA-SbGHtWu44W4BSbtmy4F6Rhae21myZ_OFxaWM可以正常登录, 也能正常获取用户信息
剑鸣秋朔