Files
Edu/services/api-gateway/README.md
SpecialX e5902ca2b3 fix(api-gateway): 修复尾斜杠重定向循环与 DEV_MODE 旁路
- main.go: 禁用 RedirectTrailingSlash,为 classes/iam/teacher 双注册无尾斜杠与通配符路由

- auth.go: DEV_MODE=true 时接受 Bearer dev-token 注入开发用户

- config.go: 新增 DevMode 配置项与 getEnvBool 工具

- page.tsx: 开发模式请求携带 Authorization: Bearer dev-token

- .env.example: 添加 DEV_MODE=false 默认值与生产警告
2026-07-08 15:11:47 +08:00

96 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API Gateway
Go (Gin) 实现的 API 网关,所有外部请求的统一入口。
## 职责
- **路由转发**`/api/v1/classes/*` → classes 服务P1后续阶段追加 iam/core-edu/content/msg 等路由
- **JWT 鉴权**P1 HS256测试密钥P2 起 RS256IAM 签发Gateway 公钥校验)
- **请求 ID 注入**:生成或透传 `X-Request-ID`,全链路追踪
- **限流**P6基于令牌桶的 per-IP 限流,超限返回 429
- **熔断**P6基于 gobreaker v2 的下游服务熔断5xx 错误率 > 50% 触发 OPEN
- **CORS / 安全头 / Recovery**P6标准化中间件链
## 中间件链P6
请求处理顺序(自外向内):
```
Request → RequestID → CORS → Security → Recovery → RateLimit → Auth → CircuitBreaker → Proxy → Response
```
| 中间件 | 文件 | 职责 |
| -------------- | ---------------------------------------- | -------------------------------------------- |
| RequestID | `internal/middleware/requestid.go` | 生成/透传 `X-Request-ID` |
| CORS | `internal/middleware/cors.go` | 跨域允许 |
| Security | `internal/middleware/security.go` | 安全响应头X-Content-Type-Options 等) |
| Recovery | `internal/middleware/recovery.go` | panic 兜底返回 500 |
| RateLimit | `internal/middleware/ratelimit.go` | per-IP 令牌桶限流,超限 429 |
| Auth | `internal/middleware/auth.go` | JWT 校验,注入 `x-user-id`/`x-user-roles` 头 |
| CircuitBreaker | `internal/middleware/circuit-breaker.go` | 下游 5xx 错误率 > 50% 触发熔断,返回 503 |
## 健康检查
| 端点 | 用途 | 鉴权 |
| -------------- | ---------------------------------------- | ---- |
| `GET /healthz` | 存活探针liveness | 无 |
| `GET /readyz` | 就绪探针readiness | 无 |
| `GET /health` | 兼容端点(返回 `{ status, timestamp }` | 无 |
## 开发
```bash
cd services/api-gateway
go mod tidy
go run main.go
```
## 测试
```bash
# 单元 + 集成测试
cd services/api-gateway
go test ./internal/middleware/... -v -cover
# 测试覆盖
# - circuit-breaker_test.go: 5 用例ClosedToOpen / OpenToHalfOpen / HalfOpenToClosed / HalfOpenToOpen / 4xxNotCounted
# - ratelimit_test.go: 5 用例AllowUnderBurst / RejectOverBurst / RefillTokens / PerIPIsolation / CleanupExpiredBuckets
```
## 构建
```bash
# 本地构建
go build ./...
# Docker 构建
docker build -t edu/api-gateway .
```
## 配置
通过环境变量配置(见 `internal/config/config.go`
| 变量 | 默认值 | 说明 |
| ----------------------------- | --------------------- | ------------------------------------------------------ |
| `API_GATEWAY_PORT` | 8080 | 监听端口 |
| `JWT_SECRET` | (必填) | HS256 签名密钥P1 |
| `JWT_ISSUER` | next-edu-cloud | JWT 签发者 |
| `JWT_AUDIENCE` | next-edu-cloud | JWT 受众 |
| `DEV_MODE` | false | 开发模式旁路true 时接受 `Bearer dev-token`(仅本地) |
| `CLASSES_SERVICE_URL` | http://localhost:3001 | classes 服务地址 |
| `IAM_SERVICE_URL` | http://localhost:3002 | iam 服务地址 |
| `TEACHER_BFF_URL` | http://localhost:3003 | teacher-bff 服务地址 |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | http://localhost:4318 | OpenTelemetry OTLP 端点 |
| `LOG_LEVEL` | info | 日志级别 |
> **生产环境警告**`DEV_MODE` 必须为 `false` 或不设。设为 `true` 会允许 `dev-token` 旁路鉴权并注入固定 admin 身份。
## 关联文档
- [架构影响地图](../../docs/architecture/004_architecture_impact_map.md)
- [项目规则](../../.trae/rules/project_rules.md)
- [P6 硬化 Runbook](../../docs/architecture/runbooks/p6-hardening.md)
- [P6 后续工作手册](../../docs/architecture/runbooks/post-p6-followup.md)
- [Helm Chart](../../infra/k8s/helm/api-gateway/)