Files
gemini-banlancer/internal/middleware/auth.go
2025-11-20 12:24:05 +08:00

83 lines
2.0 KiB
Go

// Filename: internal/middleware/auth.go
package middleware
import (
"gemini-balancer/internal/service"
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
// === API Admin 认证管道 (/admin/* API路由) ===
func APIAdminAuthMiddleware(securityService *service.SecurityService) gin.HandlerFunc {
return func(c *gin.Context) {
tokenValue := extractBearerToken(c)
if tokenValue == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization token is missing"})
return
}
authToken, err := securityService.AuthenticateToken(tokenValue)
if err != nil || !authToken.IsAdmin {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid or non-admin token"})
return
}
c.Set("adminUser", authToken)
c.Next()
}
}
// === /v1 Proxy 认证 ===
func ProxyAuthMiddleware(securityService *service.SecurityService) gin.HandlerFunc {
return func(c *gin.Context) {
tokenValue := extractProxyToken(c)
if tokenValue == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "API key is missing from request"})
return
}
authToken, err := securityService.AuthenticateToken(tokenValue)
if err != nil {
// 通用信息,避免泄露过多信息
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid or inactive token provided"})
return
}
c.Set("authToken", authToken)
c.Next()
}
}
func extractProxyToken(c *gin.Context) string {
if key := c.Query("key"); key != "" {
return key
}
authHeader := c.GetHeader("Authorization")
if authHeader != "" {
if strings.HasPrefix(authHeader, "Bearer ") {
return strings.TrimPrefix(authHeader, "Bearer ")
}
}
if key := c.GetHeader("X-Api-Key"); key != "" {
return key
}
if key := c.GetHeader("X-Goog-Api-Key"); key != "" {
return key
}
return ""
}
// === 辅助函数 ===
func extractBearerToken(c *gin.Context) string {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
return ""
}
parts := strings.Split(authHeader, " ")
if len(parts) == 2 && parts[0] == "Bearer" {
return parts[1]
}
return ""
}