Fix Services & Update the middleware && others

This commit is contained in:
XOF
2025-11-24 04:48:07 +08:00
parent 3a95a07e8a
commit f2706d6fc8
37 changed files with 4458 additions and 1166 deletions

View File

@@ -1,4 +1,5 @@
// Filename: internal/middleware/auth.go
package middleware
import (
@@ -7,76 +8,115 @@ import (
"strings"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
// === API Admin 认证管道 (/admin/* API路由) ===
type ErrorResponse struct {
Error string `json:"error"`
Code string `json:"code,omitempty"`
}
func APIAdminAuthMiddleware(securityService *service.SecurityService) gin.HandlerFunc {
// APIAdminAuthMiddleware 管理后台 API 认证
func APIAdminAuthMiddleware(
securityService *service.SecurityService,
logger *logrus.Logger,
) gin.HandlerFunc {
return func(c *gin.Context) {
tokenValue := extractBearerToken(c)
if tokenValue == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization token is missing"})
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrorResponse{
Error: "Authentication required",
Code: "AUTH_MISSING",
})
return
}
// ✅ 只传 token 参数(移除 context
authToken, err := securityService.AuthenticateToken(tokenValue)
if err != nil || !authToken.IsAdmin {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid or non-admin token"})
if err != nil {
logger.WithError(err).Warn("Authentication failed")
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrorResponse{
Error: "Invalid authentication",
Code: "AUTH_INVALID",
})
return
}
if !authToken.IsAdmin {
c.AbortWithStatusJSON(http.StatusForbidden, ErrorResponse{
Error: "Admin access required",
Code: "AUTH_FORBIDDEN",
})
return
}
c.Set("adminUser", authToken)
c.Next()
}
}
// === /v1 Proxy 认证 ===
func ProxyAuthMiddleware(securityService *service.SecurityService) gin.HandlerFunc {
// ProxyAuthMiddleware 代理请求认证
func ProxyAuthMiddleware(
securityService *service.SecurityService,
logger *logrus.Logger,
) 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"})
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrorResponse{
Error: "API key required",
Code: "KEY_MISSING",
})
return
}
// ✅ 只传 token 参数(移除 context
authToken, err := securityService.AuthenticateToken(tokenValue)
if err != nil {
// 通用信息,避免泄露过多信息
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid or inactive token provided"})
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrorResponse{
Error: "Invalid API key",
Code: "KEY_INVALID",
})
return
}
c.Set("authToken", authToken)
c.Next()
}
}
// extractProxyToken 按优先级提取 token
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 ")
}
// 优先级 1: Authorization Header
if token := extractBearerToken(c); token != "" {
return token
}
// 优先级 2: X-Api-Key
if key := c.GetHeader("X-Api-Key"); key != "" {
return key
}
// 优先级 3: X-Goog-Api-Key
if key := c.GetHeader("X-Goog-Api-Key"); key != "" {
return key
}
return ""
// 优先级 4: Query 参数(不推荐)
return c.Query("key")
}
// === 辅助函数 ===
// extractBearerToken 提取 Bearer Token
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]
const prefix = "Bearer "
if !strings.HasPrefix(authHeader, prefix) {
return ""
}
return ""
return strings.TrimSpace(authHeader[len(prefix):])
}