187 lines
3.9 KiB
Markdown
187 lines
3.9 KiB
Markdown
|
|
# LingAdmin API Gateway
|
||
|
|
|
||
|
|
API 网关服务 - 负责请求路由、认证、限流、日志记录等功能。
|
||
|
|
|
||
|
|
## 服务信息
|
||
|
|
|
||
|
|
| 属性 | 值 |
|
||
|
|
|------|-----|
|
||
|
|
| 端口 | 5000 |
|
||
|
|
| Dapr App ID | api-gateway |
|
||
|
|
| Dapr HTTP Port | 3500 |
|
||
|
|
|
||
|
|
## 核心功能
|
||
|
|
|
||
|
|
### 1. 请求路由 (YARP)
|
||
|
|
|
||
|
|
使用 YARP (Yet Another Reverse Proxy) 进行请求路由:
|
||
|
|
|
||
|
|
| 路由规则 | 目标服务 | 需要认证 |
|
||
|
|
|----------|----------|----------|
|
||
|
|
| /api/auth/* | identity-service | ❌ |
|
||
|
|
| /api/users/* | identity-service | ✅ |
|
||
|
|
| /api/roles/* | authorization-service | ✅ |
|
||
|
|
| /api/authorization/* | authorization-service | ❌/✅ |
|
||
|
|
| /api/permissions/* | authorization-service | ✅ |
|
||
|
|
|
||
|
|
### 2. JWT 认证
|
||
|
|
|
||
|
|
- 验证所有带 `Authorization: Bearer <token>` 的请求
|
||
|
|
- 配置必须与 Identity Service 保持一致
|
||
|
|
|
||
|
|
### 3. 请求限流
|
||
|
|
|
||
|
|
- 基于 IP 地址限流
|
||
|
|
- 默认限制: 100 次请求/分钟
|
||
|
|
- 超限返回 429 状态码
|
||
|
|
|
||
|
|
### 4. 请求日志
|
||
|
|
|
||
|
|
- 记录请求开始和结束
|
||
|
|
- 记录响应状态码和耗时
|
||
|
|
- 添加请求追踪 ID (X-Request-Id)
|
||
|
|
|
||
|
|
## API 端点
|
||
|
|
|
||
|
|
### 健康检查
|
||
|
|
|
||
|
|
| 方法 | 路径 | 描述 |
|
||
|
|
|------|------|------|
|
||
|
|
| GET | `/api/health` | 网关健康状态 |
|
||
|
|
| GET | `/api/health/services` | 所有服务健康状态 |
|
||
|
|
|
||
|
|
## 启动方式
|
||
|
|
|
||
|
|
### 独立启动
|
||
|
|
```powershell
|
||
|
|
cd LingAdmin.ApiGateway
|
||
|
|
dotnet run
|
||
|
|
```
|
||
|
|
|
||
|
|
### 使用 Dapr 启动
|
||
|
|
```powershell
|
||
|
|
dapr run --app-id api-gateway --app-port 5000 --dapr-http-port 3500 --resources-path ../dapr/components -- dotnet run
|
||
|
|
```
|
||
|
|
|
||
|
|
## 配置说明
|
||
|
|
|
||
|
|
### appsettings.json
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"JwtSettings": {
|
||
|
|
"SecretKey": "与其他服务相同的 JWT 密钥",
|
||
|
|
"Issuer": "Token 发行者",
|
||
|
|
"Audience": "Token 接收者"
|
||
|
|
},
|
||
|
|
"Services": {
|
||
|
|
"IdentityService": {
|
||
|
|
"BaseUrl": "http://localhost:5001",
|
||
|
|
"DaprAppId": "identity-service"
|
||
|
|
},
|
||
|
|
"AuthorizationService": {
|
||
|
|
"BaseUrl": "http://localhost:5002",
|
||
|
|
"DaprAppId": "authorization-service"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"ReverseProxy": {
|
||
|
|
"Routes": { ... },
|
||
|
|
"Clusters": { ... }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 路由配置
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"ReverseProxy": {
|
||
|
|
"Routes": {
|
||
|
|
"auth-route": {
|
||
|
|
"ClusterId": "identity-cluster",
|
||
|
|
"Match": {
|
||
|
|
"Path": "/api/auth/{**catch-all}"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"users-route": {
|
||
|
|
"ClusterId": "identity-cluster",
|
||
|
|
"AuthorizationPolicy": "default",
|
||
|
|
"Match": {
|
||
|
|
"Path": "/api/users/{**catch-all}"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"Clusters": {
|
||
|
|
"identity-cluster": {
|
||
|
|
"Destinations": {
|
||
|
|
"identity-service": {
|
||
|
|
"Address": "http://localhost:5001"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 添加新路由
|
||
|
|
|
||
|
|
要为新的微服务添加路由:
|
||
|
|
|
||
|
|
1. 在 `Clusters` 中添加新的集群配置
|
||
|
|
2. 在 `Routes` 中添加新的路由规则
|
||
|
|
3. 根据需要配置认证策略
|
||
|
|
|
||
|
|
示例:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"ReverseProxy": {
|
||
|
|
"Routes": {
|
||
|
|
"new-service-route": {
|
||
|
|
"ClusterId": "new-service-cluster",
|
||
|
|
"AuthorizationPolicy": "default",
|
||
|
|
"Match": {
|
||
|
|
"Path": "/api/new-service/{**catch-all}"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"Clusters": {
|
||
|
|
"new-service-cluster": {
|
||
|
|
"Destinations": {
|
||
|
|
"new-service": {
|
||
|
|
"Address": "http://localhost:5003"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 自定义限流
|
||
|
|
|
||
|
|
修改 `Program.cs` 中的限流配置:
|
||
|
|
|
||
|
|
```csharp
|
||
|
|
builder.Services.AddRateLimiter(options =>
|
||
|
|
{
|
||
|
|
options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(context =>
|
||
|
|
RateLimitPartition.GetFixedWindowLimiter(
|
||
|
|
partitionKey: context.Connection.RemoteIpAddress?.ToString() ?? "anonymous",
|
||
|
|
factory: _ => new FixedWindowRateLimiterOptions
|
||
|
|
{
|
||
|
|
PermitLimit = 100, // 请求次数限制
|
||
|
|
Window = TimeSpan.FromMinutes(1) // 时间窗口
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## 响应头
|
||
|
|
|
||
|
|
网关会添加以下响应头:
|
||
|
|
|
||
|
|
| 头名称 | 描述 |
|
||
|
|
|--------|------|
|
||
|
|
| X-Request-Id | 请求唯一标识 |
|
||
|
|
| X-Correlation-Id | 关联 ID (从请求头传递或新生成) |
|