问题描述
文件: frontend/src/shared/api/index.ts:217-248
当响应返回 HTTP 200 + 业务码 401 时,客户端会刷新 token 后重放请求。canReplay 函数仅排除了 ReadableStream body:
function canReplay(options: ApiRequestOptions | undefined): boolean {
const body = options?.body
return !(typeof ReadableStream !== 'undefined' && body instanceof ReadableStream)
}
未检查 HTTP 方法。 POST、PUT、PATCH、DELETE 请求都会被重放。
风险场景
- 用户提交 POST 创建资源 → 后端部分处理后返回 401 → 客户端刷新 token → 重放 POST → 重复创建
- 用户 DELETE 资源 → 后端已删除但返回 401 → 重放 DELETE → 404 或幂等性问题
建议修复
在 canReplay 中增加方法检查:
function canReplay(options: ApiRequestOptions | undefined): boolean {
const body = options?.body
if (typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) return false
const method = options?.method?.toUpperCase()
if (method && !['GET', 'HEAD', 'OPTIONS'].includes(method)) return false
return true
}
或为非幂等方法的 401 直接抛错,要求用户手动重试。
影响
- 严重程度: Medium-High
- 数据重复/意外删除
问题描述
文件:
frontend/src/shared/api/index.ts:217-248当响应返回 HTTP 200 + 业务码 401 时,客户端会刷新 token 后重放请求。
canReplay函数仅排除了ReadableStreambody:未检查 HTTP 方法。 POST、PUT、PATCH、DELETE 请求都会被重放。
风险场景
建议修复
在
canReplay中增加方法检查:或为非幂等方法的 401 直接抛错,要求用户手动重试。
影响