From 6fec141de6f9b5714bff37c400d3a785b7aa0d0c Mon Sep 17 00:00:00 2001 From: Gemini Wen Date: Mon, 19 Jan 2026 19:40:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E4=BB=A4=E7=89=8C=E5=90=8E=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=9C=AA=E6=B8=85=E9=99=A4=E5=AF=BC=E8=87=B4403=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 手动刷新令牌后,新token保存到数据库但Redis缓存未清除, 导致下游请求仍然使用旧的失效token,上游API返回403错误。 修复方案:在AccountHandler中注入TokenCacheInvalidator, 刷新令牌成功后调用InvalidateToken清除缓存。 Co-Authored-By: Claude Opus 4.5 --- backend/cmd/server/wire_gen.go | 2 +- backend/internal/handler/admin/account_handler.go | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index 9a79731b..a12d3790 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -120,7 +120,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { concurrencyService := service.ProvideConcurrencyService(concurrencyCache, accountRepository, configConfig) crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig) sessionLimitCache := repository.ProvideSessionLimitCache(redisClient, configConfig) - accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService, sessionLimitCache) + accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService, sessionLimitCache, compositeTokenCacheInvalidator) oAuthHandler := admin.NewOAuthHandler(oAuthService) openAIOAuthHandler := admin.NewOpenAIOAuthHandler(openAIOAuthService, adminService) geminiOAuthHandler := admin.NewGeminiOAuthHandler(geminiOAuthService) diff --git a/backend/internal/handler/admin/account_handler.go b/backend/internal/handler/admin/account_handler.go index 10a53f56..e7ba34e0 100644 --- a/backend/internal/handler/admin/account_handler.go +++ b/backend/internal/handler/admin/account_handler.go @@ -45,6 +45,7 @@ type AccountHandler struct { concurrencyService *service.ConcurrencyService crsSyncService *service.CRSSyncService sessionLimitCache service.SessionLimitCache + tokenCacheInvalidator service.TokenCacheInvalidator } // NewAccountHandler creates a new admin account handler @@ -60,6 +61,7 @@ func NewAccountHandler( concurrencyService *service.ConcurrencyService, crsSyncService *service.CRSSyncService, sessionLimitCache service.SessionLimitCache, + tokenCacheInvalidator service.TokenCacheInvalidator, ) *AccountHandler { return &AccountHandler{ adminService: adminService, @@ -73,6 +75,7 @@ func NewAccountHandler( concurrencyService: concurrencyService, crsSyncService: crsSyncService, sessionLimitCache: sessionLimitCache, + tokenCacheInvalidator: tokenCacheInvalidator, } } @@ -608,6 +611,14 @@ func (h *AccountHandler) Refresh(c *gin.Context) { return } + // 刷新成功后,清除 token 缓存,确保下次请求使用新 token + if h.tokenCacheInvalidator != nil { + if invalidateErr := h.tokenCacheInvalidator.InvalidateToken(c.Request.Context(), updatedAccount); invalidateErr != nil { + // 缓存失效失败只记录日志,不影响主流程 + c.Error(invalidateErr) + } + } + response.Success(c, dto.AccountFromService(updatedAccount)) }