Files
cursor/plans/callback_log_验签顺序_537cb63e.plan.md
ray zhou 225fb2bd28 ok
2026-05-29 19:26:16 +08:00

8.6 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
callback_log 验签顺序 修订需求文档与 slot-pwa 实现:将「完整 callback_log 落库」从「收包第一时间」调整为「验签通过后」;验签失败仅保留应用日志,避免未授权请求刷写分库分表。
id content status
update-docs-02 修订 02_provider_callback_log.md流程图、§5 衔接、§6 验收、安全说明 completed
id content status
update-docs-parent 同步 game_gateway_risk_prd_v_2.md §4.3/§4.4 流程顺序 completed
id content status
reorder-middleware slot-pwaPOPAuth 在前ProviderCallbackLog 在后POPAuth 去掉 DB 验签回写 in_progress
id content status
insert-verify-passed insertReceived 验签通过态写入;清理 markVerifyPassed/Failed 在 POP 路径的调用 pending
id content status
tests-verify 更新/补充 callback_log 相关测试并跑 verify-slot-backend.sh pending
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

原设计意图(合理但需边界):把每一次到达网关的请求都当作「证据」,包括验签失败,便于和 Provider 对账「对方声称发过回调」。代价是:公开 URL + 无 IP 白名单/限流时,攻击者可对 user_transaction_*.game_provider_callback_log_* 灌入大量 MEDIUMTEXTraw_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 保留 routeIPbody_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_PASSED
  • markVerifyPassed / markVerifyFailed保留方法但标注「仅兼容旧路径」或删除未引用调用POP 路径不再使用 failed 回写)
  • recordReceivedFromRequest 仅在验签后 Middleware 调用,语义与命名可在 PHPDoc 中写清

5. 测试


不在本期但必须知晓的风险

风险 缓解
验签失败无 DB 记录,与 Provider 扯皮时只能靠日志 日志字段标准化:provider_codesource_ipbody_hashx-request-id;日志保留期与 Provider 对齐
CPU 层仍可被刷验签 网关层 Provider IP 白名单 + rate limitnginx/云 WAF本期文档 § 安全说明中写为 建议项
uid=0 分片仍可能被合法但解析失败的请求写入 仅发生在验签通过后,可接受;与刷库攻击不同类

实施顺序建议

  1. 先改 02 子文档 + 父文档流程图(避免实现与需求再漂移)
  2. 调整 middleware 顺序与 POP / CallbackLog 职责
  3. Model/Service 插入时带 VERIFY_PASSED
  4. 按php-clean-code.mdc 文件验证代码规范
  5. verify-slot-backend.sh + 相关 PHPUnit