签入版本
This commit is contained in:
@@ -1,120 +1,52 @@
|
||||
# F. 中间件执行顺序
|
||||
|
||||
:::tip 概述
|
||||
本页展示请求在框架中的完整中间件执行流程,包括全局中间件和应用中间件的执行顺序,帮助开发者理解请求处理链路。
|
||||
:::tip 说明
|
||||
全局中间件链(顺序勿动):trace → CORS → metrics → response → ratelimit → demo → JWT → tenant → authz → operation_log。每个请求按此顺序穿过。
|
||||
:::
|
||||
|
||||
## 执行流程图
|
||||
## 执行表
|
||||
|
||||
```text
|
||||
请求进入
|
||||
│
|
||||
▼
|
||||
┌────────────────┐
|
||||
│ProxyMiddleware │ 全局中间件(最先执行)
|
||||
│ │ 从代理头提取真实客户端 IP
|
||||
└──────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│CorsMiddleware│ 全局中间件
|
||||
│ │ 处理 OPTIONS 预检 + 跨域响应头
|
||||
└──────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐ 401
|
||||
│AuthMiddleware│──────────► 未认证(Token 缺失/无效/过期)
|
||||
│ │ 403
|
||||
│ JWT认证 │──────────► 无权限
|
||||
│ 权限校验 │
|
||||
└──────┬───────┘
|
||||
│ 注入 userInfo
|
||||
▼
|
||||
┌──────────────┐ 403
|
||||
│TenantMiddleware│──────────► 租户异常(禁用/过期)
|
||||
│ │
|
||||
│ 租户上下文 │
|
||||
└──────┬───────┘
|
||||
│ 注入 tenantId, tenantInfo
|
||||
▼
|
||||
┌──────────────┐ 403
|
||||
│DemoMiddleware│──────────► 演示环境禁止写操作
|
||||
└──────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ LogMiddleware│ 记录操作日志(写操作始终记录)
|
||||
└──────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ 控制器方法 │
|
||||
└──────────────┘
|
||||
```
|
||||
| # | 中间件 | 职责 | 拦截行为 | ctx 写入 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | Trace | trace_id + 请求元信息 | 不拦截 | trace_id、IP、UA、方法、URL |
|
||||
| 2 | CORS | 跨域响应头 | OPTIONS 204 终止 | 无 |
|
||||
| 3 | Metrics | Prometheus 计数/耗时 | 不拦截 | 无 |
|
||||
| 4 | Response | 统一信封 + panic 恢复 | 错误时写信封终止 | 响应码/体记录 |
|
||||
| 5 | RateLimit | 固定窗口限流 | 超限拒绝 | 拒绝原因 |
|
||||
| 6 | Demo | 演示模式拒写 | 非 GET/HEAD/OPTIONS 且非公开路径拒绝 | 无 |
|
||||
| 7 | JWT | 令牌解析、身份注入 | 401 | 身份、jti/exp、角色权限 |
|
||||
| 8 | Tenant | 租户状态校验 | 禁用/过期拒绝 | 无(读身份) |
|
||||
| 9 | Authz | 功能权限校验 | 403 | 拒绝原因 |
|
||||
| 10 | OperationLog | 操作日志异步落库 | 不拦截 | 无(读响应记录) |
|
||||
|
||||
## 中间件职责
|
||||
另有链外兜底:`gin.CustomRecovery`(静态资源等业务链之外的 panic)。
|
||||
|
||||
| 中间件 | 类型 | 职责 | 配置 |
|
||||
|--------|------|------|------|
|
||||
| ProxyMiddleware | 全局 | 代理头解析,提取真实客户端 IP | .env → `[API]` PROXY_IPS |
|
||||
| CorsMiddleware | 全局 | 跨域处理 | config/cors.php |
|
||||
| AuthMiddleware | 路由级 | JWT 认证 + 权限校验 | config/middleware.php → auth_except |
|
||||
| TenantMiddleware | 路由级 | 租户上下文注入 | 内置排除列表 |
|
||||
| DemoMiddleware | 路由级 | 演示环境拦截 | .env → [APP] DEMO |
|
||||
| LogMiddleware | 路由级 | 操作日志记录 | config/middleware.php → log_except |
|
||||
## 顺序约束理由
|
||||
|
||||
## 排除配置
|
||||
- trace 最先:后续一切日志依赖 trace_id
|
||||
- Response 在业务前:panic 恢复包住全部 handler;错误出口统一
|
||||
- ratelimit/demo 在身份前:防未认证高频攻击
|
||||
- JWT → tenant → authz 逐层依赖前置注入的身份
|
||||
- operation_log 链尾:须读到最终响应才采集
|
||||
|
||||
```php
|
||||
// config/middleware.php
|
||||
return [
|
||||
'auth_except' => [
|
||||
'login',
|
||||
'captcha',
|
||||
'oauth2/token',
|
||||
'oauth2/check/token',
|
||||
],
|
||||
'log_except' => [
|
||||
'login',
|
||||
'logout',
|
||||
'captcha',
|
||||
'oauth2',
|
||||
],
|
||||
];
|
||||
```
|
||||
## 免登录判定(IsPublicRequest)
|
||||
|
||||
## 注入内容
|
||||
两个来源汇合:
|
||||
|
||||
| 中间件 | 注入字段 | 说明 |
|
||||
|--------|---------|------|
|
||||
| ProxyMiddleware | `$_SERVER['REMOTE_ADDR']` | 覆盖为真实客户端 IP |
|
||||
| AuthMiddleware | `$request->userInfo` | 用户信息(uid, username, type 等) |
|
||||
| TenantMiddleware | `$request->tenantId` | 租户 ID(0=超级管理员) |
|
||||
| TenantMiddleware | `$request->isSuperAdmin` | 是否超级管理员 |
|
||||
| TenantMiddleware | `$request->tenantInfo` | 租户信息对象 |
|
||||
| 来源 | 内容 |
|
||||
|---|---|
|
||||
| 基础设施白名单 | /api/health、/api.json、/swagger*、/metrics |
|
||||
| 路由元数据 | RouteSpec.Public=true(登录/验证码/令牌兑换) |
|
||||
|
||||
## ProxyMiddleware 详解
|
||||
## 拒绝类请求的可观测差异
|
||||
|
||||
当项目部署在 CDN / 负载均衡 / Nginx 反向代理后面时,PHP 的 `REMOTE_ADDR` 是代理服务器的 IP(通常是 `127.0.0.1`),真实客户端 IP 由代理通过 `X-Forwarded-For` / `X-Real-IP` 请求头传递。
|
||||
| 拒绝 | 操作日志 | metrics 归类 |
|
||||
|---|---|---|
|
||||
| 限流 / 权限 403 | 不记录 | denied |
|
||||
| 租户拒绝 | 不记录 | error |
|
||||
| 未认证 401 | 不记录 | —(JWT 层) |
|
||||
|
||||
### 工作原理
|
||||
## 相关
|
||||
|
||||
```text
|
||||
客户端(真实IP) → CDN/代理 → Nginx → PHP-FPM
|
||||
↓ 设置头
|
||||
X-Forwarded-For: 真实IP, 代理IP
|
||||
X-Real-IP: 真实IP
|
||||
```
|
||||
|
||||
1. 检查 `REMOTE_ADDR` 是否在受信代理列表(`.env` → `PROXY_IPS`)
|
||||
2. 如果是,从 `X-Real-IP` 或 `X-Forwarded-For` 头提取真实 IP
|
||||
3. 覆盖 `$_SERVER['REMOTE_ADDR']`,后续 `request()->ip()` 返回真实 IP
|
||||
|
||||
### 配置
|
||||
|
||||
```ini
|
||||
# .env [API] 段
|
||||
# 受信代理 IP(逗号分隔,支持 CIDR 网段)
|
||||
# 未配置时默认信任 127.0.0.1 和 ::1
|
||||
PROXY_IPS = 127.0.0.1,::1,101.226.0.0/15,180.101.0.0/16
|
||||
```
|
||||
- [4.2 请求处理链路](/zh/architecture/request-flow.html)
|
||||
- [5.17 链路追踪与指标](/zh/core/trace-metrics.html)
|
||||
|
||||
Reference in New Issue
Block a user