fix: 后台自动刷新纳入 setup-token 账号(修复 8h 后 401)#3883
Merged
Merged
Conversation
setup-token 的 access_token 同为 8h 短期令牌(expires_in=28800), 此前被后台刷新服务排除,到期后请求返回 401 authentication_error。 放开 CanRefresh 与候选查询的 type='oauth' 限制,与手动刷新入口 (account.IsOAuth()) 保持一致;实际刷新仍由 NeedsRefresh 基于 expires_at 门控并在分布式锁下执行,不会过度刷新。
Contributor
|
All contributors have signed the CLA. ✅ |
Contributor
Author
|
I have read the CLA Document and I hereby sign the CLA |
|
我终于知道为什么动不动就给我报credential invalid了😭 |
- ListOAuthRefreshCandidates SQL 断言由 type = 'oauth' 改为
type IN ('oauth', 'setup-token')。
- ClaudeTokenRefresher.CanRefresh 增加 anthropic setup-token → true 用例。
Contributor
Author
|
已修复此前 CI 单测失败:
本地已用 当前 CI/Security Scan 显示 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题现象
setup-token类型的 Anthropic 账号在使用约 8 小时后开始返回 401authentication_error,随后触发 failover。根因
setup-token的 access_token 与oauth一样是短期令牌——上游返回expires_in=28800(即 8 小时),并非之前假设的「有效期 1 年」。但后台自动刷新服务故意排除了 setup-token:service/token_refresher.go的ClaudeTokenRefresher.CanRefresh()只认Type == AccountTypeOAuth,注释写着「setup-token 有效期1年,不需要频繁刷新」——与实际的 8h 不符。repository/account_repo.go的ListOAuthRefreshCandidates候选查询限定AND type = 'oauth',同样把 setup-token 排除在外。于是 setup-token 的 access_token 到期后没有任何人续期,转发路径又直接读库里的 token 照发,Anthropic 返回 401(响应带 request_id,可确认是真打到上游、非本地判过期)。
而手动刷新是支持 setup-token 的:
refreshSingleAccount的守卫用的是account.IsOAuth(),它返回oauth || setup-token。也就是说能力本就具备,只是后台定时路径没走到。改动
让后台刷新与手动入口保持一致:
ClaudeTokenRefresher.CanRefresh():Type == AccountTypeOAuth→account.IsOAuth()(涵盖 oauth 与 setup-token),并修正注释。ListOAuthRefreshCandidates候选查询:AND type = 'oauth'→AND type IN ('oauth', 'setup-token')。为什么安全(不会过度刷新 / 不会打乱现有逻辑)
NeedsRefresh基于expires_at门控,只在临近到期时才刷——不是每轮强刷。OAuthRefreshAPI.RefreshIfNeeded的分布式锁 + DB 重读 + 竞争恢复下执行,多 worker 并发安全。Type == AccountTypeOAuth兜底,不受影响。验证
go build ./internal/service/... ./internal/repository/...通过。POST /admin/accounts/:id/refresh)验证过 setup-token 的刷新链路可用:走代理刷新、轮换并存回新 refresh_token、同步 Postgres + Redis 快照,账号有效期回到 ~8h、401 消失。本 PR 把同一能力回归到后台定时路径。