Files
yinghuoapi/backend/internal/service/gemini_native_signature_cleaner.go
liuxiongfeng 6baf810885 fix(gemini): 导出 DummyThoughtSignature 常量并修复跨账号签名验证
- 将 dummyThoughtSignature 改为导出的 DummyThoughtSignature 常量,供跨包使用
- 修改 gemini_native_signature_cleaner.go 将删除签名改为替换为 dummy 签名
  这样可以跳过 Gemini 3 的签名验证,解决粘性会话切换账号时的验证失败问题
- 更新相关测试文件

Fixes: 粘性会话切换账号时 thoughtSignature 验证失败导致 400 错误
2026-02-03 21:34:55 +08:00

76 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"encoding/json"
"github.com/Wei-Shaw/sub2api/internal/pkg/antigravity"
)
// CleanGeminiNativeThoughtSignatures 从 Gemini 原生 API 请求中替换 thoughtSignature 字段为 dummy 签名,
// 以避免跨账号签名验证错误。
//
// 当粘性会话切换账号时(例如原账号异常、不可调度等),旧账号返回的 thoughtSignature
// 会导致新账号的签名验证失败。通过替换为 dummy 签名,跳过签名验证。
//
// CleanGeminiNativeThoughtSignatures replaces thoughtSignature fields with dummy signature
// in Gemini native API requests to avoid cross-account signature validation errors.
//
// When sticky session switches accounts (e.g., original account becomes unavailable),
// thoughtSignatures from the old account will cause validation failures on the new account.
// By replacing with dummy signature, we skip signature validation.
func CleanGeminiNativeThoughtSignatures(body []byte) []byte {
if len(body) == 0 {
return body
}
// 解析 JSON
var data any
if err := json.Unmarshal(body, &data); err != nil {
// 如果解析失败,返回原始 body可能不是 JSON 或格式不正确)
return body
}
// 递归替换 thoughtSignature 为 dummy 签名
replaced := replaceThoughtSignaturesRecursive(data)
// 重新序列化
result, err := json.Marshal(replaced)
if err != nil {
// 如果序列化失败,返回原始 body
return body
}
return result
}
// replaceThoughtSignaturesRecursive 递归遍历数据结构,将所有 thoughtSignature 字段替换为 dummy 签名
func replaceThoughtSignaturesRecursive(data any) any {
switch v := data.(type) {
case map[string]any:
// 创建新的 map替换 thoughtSignature 为 dummy 签名
result := make(map[string]any, len(v))
for key, value := range v {
// 替换 thoughtSignature 字段为 dummy 签名
if key == "thoughtSignature" {
result[key] = antigravity.DummyThoughtSignature
continue
}
// 递归处理嵌套结构
result[key] = replaceThoughtSignaturesRecursive(value)
}
return result
case []any:
// 递归处理数组中的每个元素
result := make([]any, len(v))
for i, item := range v {
result[i] = replaceThoughtSignaturesRecursive(item)
}
return result
default:
// 基本类型string, number, bool, null直接返回
return v
}
}