文档目录
API授权控制

简介

本文件面向DouPHP的API授权控制系统,系统性说明API接口的认证机制、会话管理、用户身份识别、中间件拦截流程、接口级与方法级权限控制、限流防刷策略、密钥与安全配置,以及测试与调试方法。重点围绕以下实现:

  • Token验证:基于不透明随机token的生命周期管理与校验
  • 会话管理:通过Guard将解析出的用户上下文注入到当前请求生命周期
  • 用户身份识别:会员ID与工作端身份的获取与校验
  • 中间件拦截:UserAuthMiddleware与ThrottleMiddleware在HTTP边界的统一处理
  • 权限控制:声明式鉴权模式(public/optional/required)与work_required子策略
  • 限流防刷:按路由+IP维度的定向限流,超限返回429并附带Retry-After
  • 安全配置:可信代理、Host白名单、响应头加固、会话Cookie硬化、限流存储路径

项目结构

API授权相关代码主要分布在以下位置:

  • 中间件层:api/middleware/ 与 core/foundation/middleware/
  • 鉴权门面与令牌服务:api/facade/Auth.php 与 core/service/user/ApiTokenService.php
  • 鉴权模式配置:api/init/middleware.php
  • 安全配置:config/security.php
  • 路由与控制器:api/route/ 与 api/controller/
graph TB
Client["客户端"] --> MW_Auth["UserAuthMiddleware<br/>API会员鉴权"]
Client --> MW_Throttle["ThrottleMiddleware<br/>定向限流"]
MW_Auth --> Guard["Auth Facade<br/>api/facade/Auth.php"]
Guard --> TokenSvc["ApiTokenService<br/>core/service/user/ApiTokenService.php"]
MW_Throttle --> Store["ThrottleStore<br/>security.throttle.store"]
MW_Auth --> Policy["鉴权模式决策<br/>api/init/middleware.php"]
Controller["业务控制器<br/>api/controller/*"] --> Guard
Controller --> DB["数据库<br/>user / user_token"]

图表来源

  • UserAuthMiddleware.php:34-93
  • ThrottleMiddleware.php:31-90
  • AbstractUserAuthMiddleware.php:124-168
  • AbstractThrottleMiddleware.php:60-84
  • Auth.php:197-255
  • ApiTokenService.php:57-124
  • middleware.php:33-146
  • security.php:74-85

章节来源

  • UserAuthMiddleware.php:34-93
  • ThrottleMiddleware.php:31-90
  • AbstractUserAuthMiddleware.php:124-168
  • AbstractThrottleMiddleware.php:60-84
  • Auth.php:197-255
  • ApiTokenService.php:57-124
  • middleware.php:33-146
  • security.php:74-85

核心组件

  • API会员鉴权中间件(UserAuthMiddleware)
    • 从请求头提取Bearer token,调用auth('api')解析用户上下文,注入Guard,并在required模式下拒绝未登录或无工作端身份
  • 定向限流中间件(ThrottleMiddleware)
    • 对敏感路由按IP进行计数限流,超限返回429并设置Retry-After
  • API鉴权门面(Auth)
    • 实现GuardContract,提供id()/check()/guest()/workId()/work()等读接口,以及resolveUserContext/hydrate/checkLoginState等鉴权入口
  • API令牌服务(ApiTokenService)
    • 负责不透明随机token的签发、解析、吊销;仅存hash,支持过期清理与心跳刷新
  • 鉴权模式配置(api/init/middleware.php)
    • 声明式auth_modes与work_required,决定模块/动作的鉴权级别与工作端要求
  • 安全配置(config/security.php)
    • 可信代理、可信Host、安全响应头、限流存储路径、会话Cookie硬化

章节来源

  • UserAuthMiddleware.php:34-93
  • ThrottleMiddleware.php:31-90
  • Auth.php:72-181
  • ApiTokenService.php:26-158
  • middleware.php:33-146
  • security.php:51-85

架构总览

API请求进入后,先经过限流中间件进行配额检查,再进入鉴权中间件完成Token解析与用户上下文注入,最后交由控制器执行业务逻辑。

sequenceDiagram
participant C as "客户端"
participant T as "ThrottleMiddleware"
participant A as "UserAuthMiddleware"
participant G as "Auth Facade"
participant S as "ApiTokenService"
participant Ctrl as "业务控制器"
C->>T : HTTP请求
T->>T : 计算路由键与配额
alt 超限
T-->>C : 429 + Retry-After
else 未超限
T->>A : 放行
A->>G : resolveUserContext(bearerToken)
G->>S : resolve(token)
S-->>G : userId(或0)
G-->>A : 用户上下文(ok, userId, work...)
alt required且未登录
A-->>C : 401
else required且无work身份
A-->>C : 403
else 通过
A->>Ctrl : 继续处理
Ctrl-->>C : 业务响应
end
end

图表来源

  • AbstractThrottleMiddleware.php:60-84
  • ThrottleMiddleware.php:64-89
  • AbstractUserAuthMiddleware.php:124-168
  • UserAuthMiddleware.php:47-93
  • Auth.php:197-255
  • ApiTokenService.php:92-124

详细组件分析

UserAuthMiddleware:请求拦截、Token解析与用户状态检查

  • 职责边界
    • 从请求头读取Bearer token,调用auth('api')->resolveUserContext(token)解析上下文
    • 将上下文注入Guard(hydrate),供后续控制器使用
    • 根据鉴权模式(public/optional/required)与工作端策略(work_required)决定是否放行或拒绝
  • 关键行为
    • 未登录且required:返回401 JSON错误
    • 已登录但无工作端身份且work_required:返回403 JSON错误
    • optional/public:匿名访问或增强态访问均放行
  • 配置来源
    • 配置文件路径由configFile()返回,加载api/init/middleware.php中的auth_modes与work_required
flowchart TD
Start(["进入中间件"]) --> ReadMode["读取鉴权模式<br/>public/optional/required"]
ReadMode --> ModeCheck{"模式为public?"}
ModeCheck --> |是| Next1["直接放行"]
ModeCheck --> |否| Resolve["解析Token上下文"]
Resolve --> Ok{"ok=true?"}
Ok --> |否| Required{"required?"}
Required --> |是| Reject401["返回401"]
Required --> |否| Next2["放行可选登录态"]
Ok --> |是| Inject["注入用户上下文"]
Inject --> WorkReq{"work_required?"}
WorkReq --> |是| HasWork{"有work身份?"}
HasWork --> |否| Reject403["返回403"]
HasWork --> |是| Next3["放行"]
WorkReq --> |否| Next3

图表来源

  • AbstractUserAuthMiddleware.php:124-168
  • UserAuthMiddleware.php:47-93
  • middleware.php:33-146

章节来源

  • UserAuthMiddleware.php:34-93
  • AbstractUserAuthMiddleware.php:124-168
  • middleware.php:33-146

ThrottleMiddleware:API限流与防刷

  • 职责边界
    • 针对敏感路由(登录、注册、找回密码、短信验证码、公共写接口、防伪查询、LLM成本端点)按IP进行限流
    • 超限返回429并设置Retry-After头
  • 配额策略
    • 通过throttleFor(module, action, sub)匹配精确/父段/模块根级别的配额表
    • 默认不限流,仅显式配额的端点生效
  • 存储与键
    • 限流键默认module.action.ip
    • 存储目录来自security.throttle.store
flowchart TD
Enter(["进入限流中间件"]) --> GetRoute["获取module/action/sub"]
GetRoute --> Lookup["查找配额表"]
Lookup --> Found{"找到配额?"}
Found --> |否| Pass["放行"]
Found --> |是| Check["统计次数/窗口"]
Check --> TooMany{"超过max?"}
TooMany --> |是| Reject["返回429 + Retry-After"]
TooMany --> |否| Hit["记录一次命中"]
Hit --> Pass

图表来源

  • AbstractThrottleMiddleware.php:60-84
  • ThrottleMiddleware.php:38-89
  • security.php:74-77

章节来源

  • ThrottleMiddleware.php:31-90
  • AbstractThrottleMiddleware.php:60-84
  • security.php:74-77

Auth Facade与ApiTokenService:Token验证与会话管理

  • Auth Facade
    • 暴露id()/check()/guest()/workId()/work()等读接口
    • hydrate(context)将解析结果注入当前请求上下文
    • resolveUserContext(token)组合checkLoginState与用户资料/工作端信息构建上下文
    • checkLoginState(token)用于公开接口校验登录态
  • ApiTokenService
    • issue(userId, ip)签发64位十六进制随机token,持久化token_hash与过期时间
    • resolve(token)校验token有效性,支持过期清理与last_active心跳刷新
    • revoke/revokeAllForUser支持单设备与全部设备吊销
classDiagram
class Auth {
+id() int
+user() array
+check() bool
+guest() bool
+workId() int
+work() array
+hydrate(context) void
+resolveUserContext(token) array
+checkLoginState(token) array
}
class ApiTokenService {
+issue(userId, ip) string
+resolve(token) int
+revoke(token) void
+revokeAllForUser(userId) void
}
Auth --> ApiTokenService : "懒加载使用"

图表来源

  • Auth.php:72-181
  • Auth.php:197-255
  • ApiTokenService.php:57-158

章节来源

  • Auth.php:72-181
  • Auth.php:197-255
  • ApiTokenService.php:57-158

鉴权模式与工作端策略:接口级与方法级权限控制

  • 接口级权限(模块/动作/子控制器)
    • auth_modes定义每个模块或具体action的鉴权级别:public/optional/required
    • 可通过更具体的键覆盖(如module/sub/action)
  • 方法级权限(work_required)
    • work_required列表中的模块/子控制器在required基础上额外校验工作端身份
  • 典型场景
    • 会员中心、订单、资金、售后、健康档案等私有数据模块设为required
    • 内容浏览类模块设为optional,登录后增强
    • 登录注册等公开接口设为public
    • 工作端相关接口(如order/work、health/work)需具备work身份

章节来源

  • middleware.php:33-146
  • AbstractUserAuthMiddleware.php:124-168

路由与控制器集成

  • 路由声明
    • api/route/user.php定义了user模块下的GET/POST动作,包含登录注册、资料维护、微信子控制器与工作端入口
  • 控制器基类
    • BaseController承载API端专属逻辑,复用前台导航构建器,统一通过Facade与服务访问资源

章节来源

  • user.php:35-70
  • BaseController.php:38-60

依赖关系分析

  • 中间件依赖
    • UserAuthMiddleware依赖AbstractUserAuthMiddleware与api/init/middleware.php配置
    • ThrottleMiddleware依赖AbstractThrottleMiddleware与security.throttle.store
  • 鉴权链路
    • UserAuthMiddleware -> Auth Facade -> ApiTokenService -> 数据库(user_token)
    • Auth Facade -> UserService -> 工作端信息
  • 安全配置
    • security.php影响Request::ip()可信代理判定、安全响应头下发、会话Cookie属性、限流存储路径
graph LR
UAM["UserAuthMiddleware"] --> AUM["AbstractUserAuthMiddleware"]
UAM --> CFG["api/init/middleware.php"]
UAM --> AUTH["Auth Facade"]
AUTH --> ATS["ApiTokenService"]
TMW["ThrottleMiddleware"] --> ATM["AbstractThrottleMiddleware"]
TMW --> SEC["security.php(throttle.store)"]
AUTH --> DB["user_token / user"]

图表来源

  • UserAuthMiddleware.php:34-93
  • AbstractUserAuthMiddleware.php:124-168
  • ThrottleMiddleware.php:31-90
  • AbstractThrottleMiddleware.php:60-84
  • security.php:74-85

章节来源

  • UserAuthMiddleware.php:34-93
  • ThrottleMiddleware.php:31-90
  • security.php:74-85

性能与安全考量

  • 性能
    • 限流采用文件存储(ThrottleStore),建议部署在高可用文件系统或缓存后端;合理设置window与max避免频繁IO
    • Token解析侧存在DB查询与哈希比较,注意索引与连接池配置
    • last_active心跳更新限制为60秒内一次,降低写入压力
  • 安全
    • Token以sha256存储,防止泄露库可逆推有效凭证
    • 使用hash_equals进行恒定时间比较,防范时序攻击
    • 可信代理与Host白名单防止伪造IP与Host污染
    • 安全响应头(X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy、HSTS)加固浏览器安全
    • 会话Cookie启用HttpOnly、SameSite、Strict模式,减少XSS与CSRF风险

章节来源

  • ApiTokenService.php:92-124
  • security.php:51-85

故障排查指南

  • 401未登录
    • 检查Authorization头是否携带Bearer token
    • 确认token格式为64位十六进制字符串
    • 查看user_token表中是否存在有效且未过期的token_hash
    • 参考:UserAuthMiddleware.php:77-82、Auth.php:197-229
  • 403无工作端身份
    • 确认路由命中work_required列表
    • 检查用户是否具备work身份(workId>0)
    • 参考:UserAuthMiddleware.php:87-92、AbstractUserAuthMiddleware.php:162-165
  • 429请求被限流
    • 检查对应路由是否在ThrottleMiddleware配额表中
    • 查看security.throttle.store目录下的计数文件
    • 参考:ThrottleMiddleware.php:64-89、AbstractThrottleMiddleware.php:60-84
  • 登录态检查失败
    • 使用check_login_state接口定位reason(missing_credential/invalid_credential)
    • 参考:Auth.php:197-229

章节来源

  • UserAuthMiddleware.php:77-92
  • AbstractUserAuthMiddleware.php:162-165
  • ThrottleMiddleware.php:64-89
  • AbstractThrottleMiddleware.php:60-84
  • Auth.php:197-229

结论

DouPHP的API授权控制系统通过“中间件前置拦截 + 声明式鉴权模式 + 令牌服务”的组合,实现了高内聚、低耦合的认证与授权能力。UserAuthMiddleware负责Token解析与用户上下文注入,ThrottleMiddleware提供细粒度的限流保护,Auth Facade与ApiTokenService共同完成不透明token的全生命周期管理。配合安全配置与路由声明,系统能够在保证安全性的同时具备良好的可扩展性与可维护性。

附录:测试与调试

  • 测试登录态校验
    • 调用user/check_login_state接口,传入Authorization: Bearer &lt;token>,观察返回msg与reason字段
    • 参考:Auth.php:197-229
  • 测试鉴权模式
    • 对public/optional/required不同路由分别发送带/不带token的请求,验证放行与拒绝行为
    • 参考:middleware.php:33-146
  • 测试工作端权限
    • 对work_required路由,确保用户具备work身份,否则应返回403
    • 参考:AbstractUserAuthMiddleware.php:162-165
  • 测试限流
    • 对受限路由高频请求,验证429与Retry-After头;检查security.throttle.store目录计数文件
    • 参考:ThrottleMiddleware.php:64-89、security.php:74-77
  • 调试Token生命周期
    • 签发后检查user_token表新增行;解析时关注过期清理与last_active心跳更新
    • 参考:ApiTokenService.php:57-124

章节来源

  • Auth.php:197-229
  • middleware.php:33-146
  • AbstractUserAuthMiddleware.php:162-165
  • ThrottleMiddleware.php:64-89
  • security.php:74-77
  • ApiTokenService.php:57-124
添加日期:2026-10-05