package middleware import ( "net/http" "strings" "github.com/gin-gonic/gin" "photography-backend/internal/service/auth" "photography-backend/internal/model/entity" ) // AuthMiddleware 认证中间件 type AuthMiddleware struct { jwtService *auth.JWTService } // NewAuthMiddleware 创建认证中间件 func NewAuthMiddleware(jwtService *auth.JWTService) *AuthMiddleware { return &AuthMiddleware{ jwtService: jwtService, } } // RequireAuth 需要认证的中间件 func (m *AuthMiddleware) RequireAuth() gin.HandlerFunc { return func(c *gin.Context) { // 从Header中获取Authorization authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, gin.H{ "error": "Authorization header is required", }) c.Abort() return } // 检查Bearer前缀 if !strings.HasPrefix(authHeader, "Bearer ") { c.JSON(http.StatusUnauthorized, gin.H{ "error": "Invalid authorization header format", }) c.Abort() return } // 提取token token := strings.TrimPrefix(authHeader, "Bearer ") // 验证token claims, err := m.jwtService.ValidateToken(token) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{ "error": "Invalid or expired token", }) c.Abort() return } // 将用户信息存入上下文 c.Set("user_id", claims.UserID) c.Set("username", claims.Username) c.Set("user_role", claims.Role) c.Next() } } // RequireRole 需要特定角色的中间件 func (m *AuthMiddleware) RequireRole(requiredRole string) gin.HandlerFunc { return func(c *gin.Context) { userRole, exists := c.Get("user_role") if !exists { c.JSON(http.StatusUnauthorized, gin.H{ "error": "User role not found in context", }) c.Abort() return } roleStr, ok := userRole.(string) if !ok { c.JSON(http.StatusUnauthorized, gin.H{ "error": "Invalid user role", }) c.Abort() return } // 检查角色权限 if !m.hasPermission(roleStr, requiredRole) { c.JSON(http.StatusForbidden, gin.H{ "error": "Insufficient permissions", }) c.Abort() return } c.Next() } } // RequireAdmin 需要管理员权限的中间件 func (m *AuthMiddleware) RequireAdmin() gin.HandlerFunc { return m.RequireRole(string(entity.UserRoleAdmin)) } // RequirePhotographer 需要摄影师权限的中间件 func (m *AuthMiddleware) RequirePhotographer() gin.HandlerFunc { return m.RequireRole(string(entity.UserRolePhotographer)) } // OptionalAuth 可选认证中间件 func (m *AuthMiddleware) OptionalAuth() gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.Next() return } if !strings.HasPrefix(authHeader, "Bearer ") { c.Next() return } token := strings.TrimPrefix(authHeader, "Bearer ") claims, err := m.jwtService.ValidateToken(token) if err != nil { c.Next() return } // 将用户信息存入上下文 c.Set("user_id", claims.UserID) c.Set("username", claims.Username) c.Set("user_role", claims.Role) c.Next() } } // GetCurrentUser 获取当前用户ID func GetCurrentUser(c *gin.Context) (uint, bool) { userID, exists := c.Get("user_id") if !exists { return 0, false } id, ok := userID.(uint) return id, ok } // GetCurrentUserRole 获取当前用户角色 func GetCurrentUserRole(c *gin.Context) (string, bool) { userRole, exists := c.Get("user_role") if !exists { return "", false } role, ok := userRole.(string) return role, ok } // GetCurrentUsername 获取当前用户名 func GetCurrentUsername(c *gin.Context) (string, bool) { username, exists := c.Get("username") if !exists { return "", false } name, ok := username.(string) return name, ok } // IsAuthenticated 检查是否已认证 func IsAuthenticated(c *gin.Context) bool { _, exists := c.Get("user_id") return exists } // IsAdmin 检查是否为管理员 func IsAdmin(c *gin.Context) bool { role, exists := GetCurrentUserRole(c) if !exists { return false } return role == string(entity.UserRoleAdmin) } // IsPhotographer 检查是否为摄影师或以上 func IsPhotographer(c *gin.Context) bool { role, exists := GetCurrentUserRole(c) if !exists { return false } return role == string(entity.UserRolePhotographer) || role == string(entity.UserRoleAdmin) } // hasPermission 检查权限 func (m *AuthMiddleware) hasPermission(userRole, requiredRole string) bool { roleLevel := map[string]int{ string(entity.UserRoleUser): 1, string(entity.UserRolePhotographer): 2, string(entity.UserRoleAdmin): 3, } userLevel, exists := roleLevel[userRole] if !exists { return false } requiredLevel, exists := roleLevel[requiredRole] if !exists { return false } return userLevel >= requiredLevel }