From 6fec141de6f9b5714bff37c400d3a785b7aa0d0c Mon Sep 17 00:00:00 2001 From: Gemini Wen Date: Mon, 19 Jan 2026 19:40:43 +0800 Subject: [PATCH 1/3] =?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)) } From 668118def17ab06bc6e00bb69686a3ca4f18ea03 Mon Sep 17 00:00:00 2001 From: Gemini Wen Date: Mon, 19 Jan 2026 19:58:09 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=81=97=E6=BC=8F?= =?UTF-8?q?=E7=9A=84=E6=B5=8B=E8=AF=95=E6=96=87=E4=BB=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=92=8Clint=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新api_contract_test.go以匹配NewAccountHandler新增的tokenCacheInvalidator参数 - 修复errcheck lint错误,显式忽略c.Error()返回值 Co-Authored-By: Claude Opus 4.5 --- backend/internal/handler/admin/account_handler.go | 2 +- backend/internal/server/api_contract_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/internal/handler/admin/account_handler.go b/backend/internal/handler/admin/account_handler.go index e7ba34e0..9cc2540d 100644 --- a/backend/internal/handler/admin/account_handler.go +++ b/backend/internal/handler/admin/account_handler.go @@ -615,7 +615,7 @@ func (h *AccountHandler) Refresh(c *gin.Context) { if h.tokenCacheInvalidator != nil { if invalidateErr := h.tokenCacheInvalidator.InvalidateToken(c.Request.Context(), updatedAccount); invalidateErr != nil { // 缓存失效失败只记录日志,不影响主流程 - c.Error(invalidateErr) + _ = c.Error(invalidateErr) } } diff --git a/backend/internal/server/api_contract_test.go b/backend/internal/server/api_contract_test.go index be8a8df8..af1409b1 100644 --- a/backend/internal/server/api_contract_test.go +++ b/backend/internal/server/api_contract_test.go @@ -441,7 +441,7 @@ func newContractDeps(t *testing.T) *contractDeps { apiKeyHandler := handler.NewAPIKeyHandler(apiKeyService) usageHandler := handler.NewUsageHandler(usageService, apiKeyService) adminSettingHandler := adminhandler.NewSettingHandler(settingService, nil, nil, nil) - adminAccountHandler := adminhandler.NewAccountHandler(adminService, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) + adminAccountHandler := adminhandler.NewAccountHandler(adminService, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) jwtAuth := func(c *gin.Context) { c.Set(string(middleware.ContextKeyUser), middleware.AuthSubject{ From a54852e1295963aceebea7f4010818e1d8359590 Mon Sep 17 00:00:00 2001 From: Gemini Wen Date: Mon, 19 Jan 2026 20:06:36 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=85API=E5=A5=91?= =?UTF-8?q?=E7=BA=A6=E6=B5=8B=E8=AF=95=E4=B8=AD=E7=BC=BA=E5=A4=B1=E7=9A=84?= =?UTF-8?q?hide=5Fccs=5Fimport=5Fbutton=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.5 --- backend/internal/server/api_contract_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/internal/server/api_contract_test.go b/backend/internal/server/api_contract_test.go index af1409b1..666ae52c 100644 --- a/backend/internal/server/api_contract_test.go +++ b/backend/internal/server/api_contract_test.go @@ -337,7 +337,8 @@ func TestAPIContracts(t *testing.T) { "fallback_model_openai": "gpt-4o", "enable_identity_patch": true, "identity_patch_prompt": "", - "home_content": "" + "home_content": "", + "hide_ccs_import_button": false } }`, },