Beefex
E
ender
BeefAPI 服务端 device_code OAuth 端点 + 浏览器授权页 + Telegram dedupe + 多 phase saga 风控综合实现复盘
87.4K tokens · ¥4.32
E
把 oauth/device 路径下所有 handler 全跑一遍,按合约 §2.5 检查 CAS、所有权校验、限流、过期同步执行 5 个不变量。
要把 5 个不变量在整个 device 目录跑一遍——我系统地走,先扫文件清单再逐个对照。涉及 ‎controller/internal/handlers/oauth/device/v2/post_device_token_v3_final_atomic_fenced.go 这种长路径,下面展示中间汇总。
已完成 50 步,扫了 17 个文件,找到 3 处违反 §2.5
42s 展开 ▾
列出 controller/oauth/device/ 下 17 个 handler 文件
查找状态写入操作,命中 8 处,其中 3 处非原子 db.Save
核对 api_key_id 所有权校验——2 处缺失,存在 IDOR 风险
查看其余 47 步(限流校验 / 熵 / 过期 / hash 存储 等 47 项检查)
核心问题集中在 ‎controller/internal/handlers/oauth/device/v2/post_device_token_v3_final_atomic_fenced.go—— 改动跨 5 个 handler、新增 2 个 helper、调整 1 个 migration:
‎controller/internal/handlers/oauth/device/v2/post_device_token_v3_final_atomic_fenced.go
+682 −565 / 1247 行
24func PostDeviceToken(c *gin.Context) {
25 var req DeviceTokenReq
26 if err := c.ShouldBindJSON(&req); err != nil {
−27 c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_request"})
+27 c.JSON(http.StatusBadRequest, ErrInvalidRequest)
28 return
29 }
30
−31 var dc DeviceCode
−32 db.Where("device_code_hash = ?", hashCode(req.DeviceCode)).First(&dc)
−33 if dc.Status == "approved" {
−34 apiKey := issueKey(dc.UserID, dc.ApiKeyID)
−35 dc.Status = "consumed"
−36 db.Save(&dc) // ❌ 非原子
−37 return jsonResp(c, apiKey)
−38 }
+31 // CAS-fenced atomic exchange (合约 §2.5 第 2 条)
+32 apiKey, err := consumeDeviceCodeAtomic(db, req.DeviceCode)
查看其余 1197
仅看变更 在编辑器打开
这是核心一处。其余 4 个 handler 的修改在 ‎controller/internal/handlers/oauth/device/v2/... 同目录,相同 pattern。要切到 build 模式整体改吗?
改吧——按 ⌘↵ 发送

// 长内容溢出设计决策