5 Commits

Author SHA1 Message Date
erio
1fc9dd7b68 feat: unified OAuth token refresh API with distributed locking
Introduce OAuthRefreshAPI as the single entry point for all OAuth token
refresh operations, eliminating the race condition where background
refresh and inline refresh could simultaneously use the same
refresh_token (fixes #1035).

Key changes:
- Add OAuthRefreshExecutor interface extending TokenRefresher with CacheKey
- Add OAuthRefreshAPI.RefreshIfNeeded with lock → DB re-read → double-check flow
- Add ProviderRefreshPolicy / BackgroundRefreshPolicy strategy types
- Simplify all 4 TokenProviders to delegate to OAuthRefreshAPI
- Rewrite TokenRefreshService.refreshWithRetry to use unified API path
- Add MergeCredentials and BuildClaudeAccountCredentials helpers
- Add 40 unit tests covering all new and modified code paths
2026-03-16 01:31:54 +08:00
shaw
dac6bc2228 fix(token-cache): 版本过时时使用最新token而非旧token
上次修复(2665230)只阻止了写入缓存,但仍返回旧token导致403。
现在版本过时时直接使用DB中的最新token返回。

- 重构 IsTokenVersionStale 为 CheckTokenVersion,返回最新account
- 消除重复DB查询,复用版本检查时已获取的account
2026-01-23 10:29:52 +08:00
shaw
2665230a09 fix(token-cache): 修复异步刷新与请求线程的缓存竞态条件
- 新增 _token_version 版本号机制,防止过期 token 污染缓存
- TokenRefreshService 刷新成功后写入版本号并清除缓存
- TokenProvider 写入缓存前检查版本,过时则跳过
- ClearError 时同步清除 token 缓存
2026-01-22 21:09:28 +08:00
yangjianbo
5b37e9aea4 fix(OAuth缓存): 修复缓存键冲突、401强制刷新及Redis降级处理
- Gemini 缓存键统一增加 gemini: 前缀,避免与其他平台命名空间冲突
- OAuth 账号 401 错误时设置 expires_at=now 并持久化,强制下次请求刷新 token
- Redis 锁获取失败时降级为无锁刷新,仅在 token 接近过期时执行,并检查 ctx 取消状态

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 19:08:07 +08:00
yangjianbo
1820389a05 feat(网关): 引入 OpenAI/Claude OAuth token 缓存
新增 OpenAI/Claude TokenProvider 与缓存键生成
扩展 OAuth 缓存失效覆盖更多平台
统一 OAuth 缓存前缀与依赖注入
2026-01-15 18:27:06 +08:00