Merge pull request #482 from IanShaw027/fix/gateway-compatibility

fix(gemini): 优化 Gemini 接口认证兼容性,支持 Authorization: Bearer
This commit is contained in:
Wesley Liddick
2026-02-04 16:50:52 +08:00
committed by GitHub

View File

@@ -26,7 +26,7 @@ func APIKeyAuthWithSubscriptionGoogle(apiKeyService *service.APIKeyService, subs
abortWithGoogleError(c, 400, "Query parameter api_key is deprecated. Use Authorization header or key instead.") abortWithGoogleError(c, 400, "Query parameter api_key is deprecated. Use Authorization header or key instead.")
return return
} }
apiKeyString := extractAPIKeyFromRequest(c) apiKeyString := extractAPIKeyForGoogle(c)
if apiKeyString == "" { if apiKeyString == "" {
abortWithGoogleError(c, 401, "API key is required") abortWithGoogleError(c, 401, "API key is required")
return return
@@ -108,25 +108,38 @@ func APIKeyAuthWithSubscriptionGoogle(apiKeyService *service.APIKeyService, subs
} }
} }
func extractAPIKeyFromRequest(c *gin.Context) string { // extractAPIKeyForGoogle extracts API key for Google/Gemini endpoints.
authHeader := c.GetHeader("Authorization") // Priority: x-goog-api-key > Authorization: Bearer > x-api-key > query key
if authHeader != "" { // This allows OpenClaw and other clients using Bearer auth to work with Gemini endpoints.
parts := strings.SplitN(authHeader, " ", 2) func extractAPIKeyForGoogle(c *gin.Context) string {
if len(parts) == 2 && parts[0] == "Bearer" && strings.TrimSpace(parts[1]) != "" { // 1) preferred: Gemini native header
return strings.TrimSpace(parts[1]) if k := strings.TrimSpace(c.GetHeader("x-goog-api-key")); k != "" {
return k
}
// 2) fallback: Authorization: Bearer <key>
auth := strings.TrimSpace(c.GetHeader("Authorization"))
if auth != "" {
parts := strings.SplitN(auth, " ", 2)
if len(parts) == 2 && strings.EqualFold(parts[0], "Bearer") {
if k := strings.TrimSpace(parts[1]); k != "" {
return k
}
} }
} }
if v := strings.TrimSpace(c.GetHeader("x-api-key")); v != "" {
return v // 3) x-api-key header (backward compatibility)
} if k := strings.TrimSpace(c.GetHeader("x-api-key")); k != "" {
if v := strings.TrimSpace(c.GetHeader("x-goog-api-key")); v != "" { return k
return v
} }
// 4) query parameter key (for specific paths)
if allowGoogleQueryKey(c.Request.URL.Path) { if allowGoogleQueryKey(c.Request.URL.Path) {
if v := strings.TrimSpace(c.Query("key")); v != "" { if v := strings.TrimSpace(c.Query("key")); v != "" {
return v return v
} }
} }
return "" return ""
} }