78 lines
2.0 KiB
Go
78 lines
2.0 KiB
Go
package middleware
|
||
|
||
import (
|
||
"ai-gateway/internal/models"
|
||
"errors"
|
||
"log"
|
||
"net/http"
|
||
"strings"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// AuthMiddleware 创建并返回一个API密钥鉴权中间件
|
||
func AuthMiddleware(db *gorm.DB) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
// 从请求头获取 Authorization 值
|
||
authHeader := c.GetHeader("Authorization")
|
||
|
||
// 检查是否为空或不以 "Bearer " 开头
|
||
if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
|
||
log.Printf("[Auth] Failed: Missing or invalid Authorization header. IP: %s", c.ClientIP())
|
||
c.JSON(http.StatusUnauthorized, gin.H{
|
||
"error": gin.H{
|
||
"message": "Missing or invalid Authorization header",
|
||
"type": "authentication_error",
|
||
},
|
||
})
|
||
c.Abort()
|
||
return
|
||
}
|
||
|
||
// 提取 Bearer token
|
||
token := strings.TrimPrefix(authHeader, "Bearer ")
|
||
if token == "" {
|
||
log.Printf("[Auth] Failed: Missing API key. IP: %s", c.ClientIP())
|
||
c.JSON(http.StatusUnauthorized, gin.H{
|
||
"error": gin.H{
|
||
"message": "Missing API key",
|
||
"type": "authentication_error",
|
||
},
|
||
})
|
||
c.Abort()
|
||
return
|
||
}
|
||
|
||
// 在数据库中查询API密钥
|
||
var apiKey models.APIKey
|
||
if err := db.Where("key = ?", token).First(&apiKey).Error; err != nil {
|
||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||
log.Printf("[Auth] Failed: Invalid API key. Key: %s, IP: %s", token, c.ClientIP())
|
||
c.JSON(http.StatusUnauthorized, gin.H{
|
||
"error": gin.H{
|
||
"message": "Invalid API key",
|
||
"type": "authentication_error",
|
||
},
|
||
})
|
||
} else {
|
||
log.Printf("[Auth] Failed: Database error during authentication. Key: %s, IP: %s, Error: %v", token, c.ClientIP(), err)
|
||
c.JSON(http.StatusInternalServerError, gin.H{
|
||
"error": gin.H{
|
||
"message": "Failed to authenticate",
|
||
"type": "internal_error",
|
||
},
|
||
})
|
||
}
|
||
c.Abort()
|
||
return
|
||
}
|
||
|
||
// 将API密钥对象存入上下文,供后续处理器使用
|
||
c.Set("apiKey", apiKey)
|
||
|
||
// 传递给下一个处理器
|
||
c.Next()
|
||
}
|
||
}
|