package middleware import ( "fmt" "net/http" "strings" "time" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" "verification-platform-backend/pkg/jwt" "verification-platform-backend/pkg/response" "github.com/gin-gonic/gin" ) func CheckAppStatus() gin.HandlerFunc { return func(c *gin.Context) { appKey := c.Param("appKey") if appKey == "" { c.Next() return } var app model.Application if err := database.DB.Where("app_key = ?", appKey).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") c.Abort() return } if app.Status == "maintenance" { response.Error(c, 503, "应用维护中,暂时无法访问") c.Abort() return } if app.Status == "stopped" { response.Error(c, 403, "应用已停止运营") c.Abort() return } c.Set("app", &app) c.Next() } } // JWT JWT中间件 func JWT() gin.HandlerFunc { return func(c *gin.Context) { fmt.Printf("JWT中间件被调用: %s %s\n", c.Request.Method, c.Request.URL.Path) var token string authHeader := c.GetHeader("Authorization") if authHeader != "" { parts := strings.SplitN(authHeader, " ", 2) if len(parts) == 2 && parts[0] == "Bearer" { token = parts[1] } } if token == "" { token = c.Query("token") } if token == "" { fmt.Printf("JWT中间件: Authorization header is required\n") response.Error(c, http.StatusUnauthorized, "Authorization header is required") c.Abort() return } claims, err := jwt.ParseToken(token) if err != nil { fmt.Printf("JWT中间件: Invalid token: %v\n", err) response.Error(c, http.StatusUnauthorized, "Invalid token") c.Abort() return } if time.Now().Unix() > claims.ExpiresAt.Unix() { fmt.Printf("JWT中间件: Token expired\n") response.Error(c, http.StatusUnauthorized, "Token expired") c.Abort() return } c.Set("user_id", claims.UserID) c.Set("username", claims.Username) c.Set("role", claims.Role) c.Set("device_id", claims.DeviceID) c.Set("instance_id", claims.InstanceID) fmt.Printf("JWT中间件: 验证成功, user_id=%d, role=%s, device_id=%s, instance_id=%s\n", claims.UserID, claims.Role, claims.DeviceID, claims.InstanceID) c.Next() } } // AdminAuth 管理员权限中间件 func AdminAuth() gin.HandlerFunc { return func(c *gin.Context) { role, exists := c.Get("role") if !exists { response.Error(c, http.StatusForbidden, "Access denied") c.Abort() return } if role != "admin" { response.Error(c, http.StatusForbidden, "Admin access required") c.Abort() return } c.Next() } } // AgentAuth 代理商授权中间件 func AgentAuth() gin.HandlerFunc { return func(c *gin.Context) { role, exists := c.Get("role") if !exists { response.Error(c, http.StatusForbidden, "Access denied") c.Abort() return } if role != "agent" && role != "admin" { response.Error(c, http.StatusForbidden, "Agent access required") c.Abort() return } c.Next() } } // PackageAuth 套餐授权中间件 func PackageAuth() gin.HandlerFunc { return func(c *gin.Context) { role, _ := c.Get("role") if role == "admin" { c.Next() return } userID, exists := c.Get("user_id") if !exists { response.Error(c, 401, "未授权") c.Abort() return } var user model.User if err := database.DB.First(&user, userID).Error; err != nil { response.Error(c, 500, "获取用户信息失败") c.Abort() return } if user.CurrentPackageID == nil { response.Error(c, 403, "您还没有购买套餐,请先购买套餐后再使用开发者功能") c.Abort() return } var userPackage model.UserPackage if err := database.DB.Where("user_id = ? AND package_id = ? AND status = ?", userID, user.CurrentPackageID, "active").First(&userPackage).Error; err != nil { response.Error(c, 403, "套餐授权已失效,请续费或重新购买套餐") c.Abort() return } if userPackage.ExpiredAt != nil && userPackage.ExpiredAt.Before(time.Now()) { response.Error(c, 403, "套餐已过期,请续费后再使用开发者功能") c.Abort() return } c.Set("user_package", &userPackage) c.Next() } } // Logger 日志中间件 func Logger() gin.HandlerFunc { return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string { return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n", param.ClientIP, param.TimeStamp.Format(time.RFC1123), param.Method, param.Path, param.Request.Proto, param.StatusCode, param.Latency, param.Request.UserAgent(), param.ErrorMessage, ) }) } // Recovery 恢复中间件 func Recovery() gin.HandlerFunc { return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) { response.Error(c, http.StatusInternalServerError, "Internal server error") }) } // Cors 跨域中间件 func Cors() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "false") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE, PATCH") c.Writer.Header().Set("Access-Control-Max-Age", "86400") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(http.StatusOK) return } c.Next() } } // RateLimit 限流中间件 func RateLimit() gin.HandlerFunc { return func(c *gin.Context) { // 这里可以实现基于Redis的限流逻辑 // 暂时跳过实现 c.Next() } }