8.6 KiB
8.6 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | |||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| callback_log 验签顺序 | 修订需求文档与 slot-pwa 实现:将「完整 callback_log 落库」从「收包第一时间」调整为「验签通过后」;验签失败仅保留应用日志,避免未授权请求刷写分库分表。 |
|
false |
callback_log 改为验签通过后落库
问题判断
你的顾虑成立。当前设计与实现是:
sequenceDiagram
participant P as Provider
participant L as ProviderCallbackLogMiddleware
participant A as POPAuthMiddleware
participant C as Controller
P->>L: HTTP callback
L->>L: INSERT callback_log verify_status=0
L->>A: next
A->>A: verify signature
alt verify fail
A->>L: UPDATE verify_failed
A-->>P: 401 JSON
else verify pass
A->>C: next
end
- 需求:02_provider_callback_log.md §3.1 / §5 要求「先 INSERT,再验签」
- 实现:middleware.php 中
ProviderCallbackLogMiddleware排在POPAuthMiddleware之前;ProviderCallbackLogMiddleware.php 注释也写明「须在验签之前」 - 验收 §6.2 要求「验签失败仍有 callback_log」——与防刷目标冲突
原设计意图(合理但需边界):把每一次到达网关的请求都当作「证据」,包括验签失败,便于和 Provider 对账「对方声称发过回调」。代价是:公开 URL + 无 IP 白名单/限流时,攻击者可对 user_transaction_*.game_provider_callback_log_* 灌入大量 MEDIUMTEXT(raw_body/raw_headers)。
你已确认的产品取舍:验签通过后才 INSERT 完整 callback_log;验签失败不落库(仅应用日志;后续可选轻量 reject 表,本期不做)。
这与资金安全主链路一致:父文档 game_gateway_risk_prd_v_2.md §5.1 将「验签 / IP 校验」的目的写明为「防止非法回调」——应先挡住非法流量,再落审计库。
目标流程
sequenceDiagram
participant P as Provider
participant A as POPAuthMiddleware
participant L as ProviderCallbackLogMiddleware
participant C as Controller
P->>A: HTTP callback
A->>A: verify signature
alt verify fail
A->>A: structured error log only
A-->>P: auth error JSON
else verify pass
A->>L: next
L->>L: INSERT callback_log verify_status=1
L->>C: next
end
要点:
- 验签失败:
Log::error保留route、IP、body_hash(可选)、error;不调用markVerifyFailed(因无log_id) - 验签通过:
insertReceived时直接verify_status = VERIFY_PASSED(1),可删除事后markVerifyPassed的 UPDATE(减少一次写) - 解析失败:仍在验签通过且已落库后,由 Logic 更新
parse_status/process_status(现有markParseFailed等不变)
文档修订(必须)
1. 02_provider_callback_log.md
| 章节 | 修改 |
|---|---|
| §1.2 In scope | 「第一时间落库」改为「验签通过后同步落库完整原始请求」 |
| §3.1 流程图 | Provider callback → 验签 → 同步写 callback_log(verify_status=1) → 解析 → … |
| §5 衔接表 | 「收到任意回调先 INSERT」改为「验签通过后 INSERT」;删除「验签完成再 UPDATE verify_status」作为主路径(保留解析/处理状态更新) |
| §6 验收 | 改写 §6.2:验签失败不落 callback_log,但应用日志可按 request_id/时间检索;新增:任意成功进入业务链路的 provider_tx 仍可 callback_log_id 追溯 raw_body |
| 新增 §(安全说明) | 明确:防刷靠「验签门禁 +(建议)网关 IP 白名单/限流」;若未来需要攻击审计,用独立 reject 表或日志平台,不污染主 callback_log |
2. game_gateway_risk_prd_v_2.md
- §4.3 / §4.4 流程图中「同步写 callback_log」节点移到「验签」之后(与 02 子文档一致)
代码修订(slot-pwa)
1. 调整 Middleware 顺序
config/middleware.php pop 组改为:
'pop' => [
\app\middleware\POPAuthMiddleware::class,
\app\middleware\ProviderCallbackLogMiddleware::class,
],
2. POPAuthMiddleware.php
- 验签失败:仅
Log::error+ 返回 JSON;移除markVerifyFailed(依赖已落库的log_id) - 验签成功:移除
markVerifyPassed;直接$handler($request)进入下一 Middleware 落库 - 平台配置缺失:同样不落库,只打日志返回错误
3. ProviderCallbackLogMiddleware.php
- 更新类注释:在验签 Middleware 之后执行,仅对验签通过的请求落库
recordReceivedFromRequest失败时:当前 catch 后仍return $handler——建议改为 记录错误并返回 5xx(避免无 callback_log 却继续扣款);与产品确认可放在实现阶段一并收紧
4. ProviderCallbackLogService.php + GameProviderCallbackLogModel.php
insertReceived增加参数或拆方法:insertReceivedAfterVerifyPassed(),写入时verify_status = VERIFY_PASSEDmarkVerifyPassed/markVerifyFailed:保留方法但标注「仅兼容旧路径」或删除未引用调用(POP 路径不再使用 failed 回写)recordReceivedFromRequest仅在验签后 Middleware 调用,语义与命名可在 PHPDoc 中写清
5. 测试
- GameProviderCallbackLogShardModelTest.php / ProviderCallbackLogTestCase.php:若直接测
insertReceived,默认VERIFY_PENDING仍可用于 Model 单测;新增或调整用例覆盖「验签后插入为 PASSED」 - 可选:Middleware 顺序集成测试(验签失败不触发 insert)——若项目已有 HTTP 测试基建则补一条
不在本期但必须知晓的风险
| 风险 | 缓解 |
|---|---|
| 验签失败无 DB 记录,与 Provider 扯皮时只能靠日志 | 日志字段标准化:provider_code、source_ip、body_hash、x-request-id;日志保留期与 Provider 对齐 |
| CPU 层仍可被刷验签 | 网关层 Provider IP 白名单 + rate limit(nginx/云 WAF);本期文档 § 安全说明中写为 建议项 |
uid=0 分片仍可能被合法但解析失败的请求写入 |
仅发生在验签通过后,可接受;与刷库攻击不同类 |
实施顺序建议
- 先改 02 子文档 + 父文档流程图(避免实现与需求再漂移)
- 调整 middleware 顺序与 POP / CallbackLog 职责
- Model/Service 插入时带
VERIFY_PASSED 按php-clean-code.mdc 文件验证代码规范- 跑
verify-slot-backend.sh+ 相关 PHPUnit