From 20f3e625297e41feb5f6e62e556ef5bd3a94dd7f Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:32:06 +0800 Subject: [PATCH] feat(auth): Add stable label to Gemini Web tokens for logging --- internal/api/handlers/management/auth_files.go | 2 ++ internal/auth/gemini/gemini-web_token.go | 14 ++++++++++++++ internal/cmd/gemini-web_auth.go | 4 ++++ sdk/cliproxy/auth/manager.go | 7 ++++--- sdk/cliproxy/auth/types.go | 15 +++++++-------- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/internal/api/handlers/management/auth_files.go b/internal/api/handlers/management/auth_files.go index 5d0c750e..a95d487e 100644 --- a/internal/api/handlers/management/auth_files.go +++ b/internal/api/handlers/management/auth_files.go @@ -714,6 +714,8 @@ func (h *Handler) CreateGeminiWebToken(c *gin.Context) { Secure1PSID: payload.Secure1PSID, Secure1PSIDTS: payload.Secure1PSIDTS, } + // Provide a stable label (gemini-web-) for logging and identification + tokenStorage.Label = strings.TrimSuffix(fileName, ".json") record := &sdkAuth.TokenRecord{ Provider: "gemini-web", diff --git a/internal/auth/gemini/gemini-web_token.go b/internal/auth/gemini/gemini-web_token.go index c0f6c81e..1fc20e4e 100644 --- a/internal/auth/gemini/gemini-web_token.go +++ b/internal/auth/gemini/gemini-web_token.go @@ -8,6 +8,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "time" "github.com/router-for-me/CLIProxyAPI/v6/internal/misc" @@ -20,12 +21,25 @@ type GeminiWebTokenStorage struct { Secure1PSIDTS string `json:"secure_1psidts"` Type string `json:"type"` LastRefresh string `json:"last_refresh,omitempty"` + // Label is a stable account identifier used for logging, e.g. "gemini-web-". + // It is derived from the auth file name when not explicitly set. + Label string `json:"label,omitempty"` } // SaveTokenToFile serializes the Gemini Web token storage to a JSON file. func (ts *GeminiWebTokenStorage) SaveTokenToFile(authFilePath string) error { misc.LogSavingCredentials(authFilePath) ts.Type = "gemini-web" + // Auto-derive a stable label from the file name if missing. + if ts.Label == "" { + base := filepath.Base(authFilePath) + if strings.HasSuffix(strings.ToLower(base), ".json") { + base = strings.TrimSuffix(base, filepath.Ext(base)) + } + if base != "" { + ts.Label = base + } + } if ts.LastRefresh == "" { ts.LastRefresh = time.Now().Format(time.RFC3339) } diff --git a/internal/cmd/gemini-web_auth.go b/internal/cmd/gemini-web_auth.go index f312122f..f6f96914 100644 --- a/internal/cmd/gemini-web_auth.go +++ b/internal/cmd/gemini-web_auth.go @@ -49,6 +49,10 @@ func DoGeminiWebAuth(cfg *config.Config) { hasher.Write([]byte(secure1psid)) hash := hex.EncodeToString(hasher.Sum(nil)) fileName := fmt.Sprintf("gemini-web-%s.json", hash[:16]) + // Set a stable label for logging, e.g. gemini-web- + if tokenStorage != nil { + tokenStorage.Label = strings.TrimSuffix(fileName, ".json") + } record := &sdkAuth.TokenRecord{ Provider: "gemini-web", FileName: fileName, diff --git a/sdk/cliproxy/auth/manager.go b/sdk/cliproxy/auth/manager.go index 72584724..edda9273 100644 --- a/sdk/cliproxy/auth/manager.go +++ b/sdk/cliproxy/auth/manager.go @@ -286,7 +286,8 @@ func (m *Manager) executeWithProvider(ctx context.Context, provider string, req } else if accountType == "oauth" { log.Debugf("Use OAuth %s for model %s", accountInfo, req.Model) } else if accountType == "cookie" { - log.Debugf("Use Cookie %s for model %s", util.HideAPIKey(accountInfo), req.Model) + // Only Gemini Web uses cookie; print stable account label as-is. + log.Debugf("Use Cookie %s for model %s", accountInfo, req.Model) } tried[auth.ID] = struct{}{} @@ -333,7 +334,7 @@ func (m *Manager) executeCountWithProvider(ctx context.Context, provider string, } else if accountType == "oauth" { log.Debugf("Use OAuth %s for model %s", accountInfo, req.Model) } else if accountType == "cookie" { - log.Debugf("Use Cookie %s for model %s", util.HideAPIKey(accountInfo), req.Model) + log.Debugf("Use Cookie %s for model %s", accountInfo, req.Model) } tried[auth.ID] = struct{}{} @@ -380,7 +381,7 @@ func (m *Manager) executeStreamWithProvider(ctx context.Context, provider string } else if accountType == "oauth" { log.Debugf("Use OAuth %s for model %s", accountInfo, req.Model) } else if accountType == "cookie" { - log.Debugf("Use Cookie %s for model %s", util.HideAPIKey(accountInfo), req.Model) + log.Debugf("Use Cookie %s for model %s", accountInfo, req.Model) } tried[auth.ID] = struct{}{} diff --git a/sdk/cliproxy/auth/types.go b/sdk/cliproxy/auth/types.go index 492cc570..c3a56cfe 100644 --- a/sdk/cliproxy/auth/types.go +++ b/sdk/cliproxy/auth/types.go @@ -129,6 +129,13 @@ func (a *Auth) AccountInfo() (string, string) { return "", "" } if strings.ToLower(a.Provider) == "gemini-web" { + // Prefer explicit label written into auth file (e.g., gemini-web-) + if a.Metadata != nil { + if v, ok := a.Metadata["label"].(string); ok && strings.TrimSpace(v) != "" { + return "cookie", strings.TrimSpace(v) + } + } + // Minimal fallback to cookie value for backward compatibility if a.Metadata != nil { if v, ok := a.Metadata["secure_1psid"].(string); ok && v != "" { return "cookie", v @@ -137,14 +144,6 @@ func (a *Auth) AccountInfo() (string, string) { return "cookie", v } } - if a.Attributes != nil { - if v := a.Attributes["secure_1psid"]; v != "" { - return "cookie", v - } - if v := a.Attributes["api_key"]; v != "" { - return "cookie", v - } - } } if a.Metadata != nil { if v, ok := a.Metadata["email"].(string); ok {