package middleware import ( "net/http" "strings" "time" "ezops/internal/config" "ezops/internal/models" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" ) // JWTClaims JWT声明 type JWTClaims struct { UserID uint `json:"user_id"` Username string `json:"username"` IsAdmin bool `json:"is_admin"` jwt.RegisteredClaims } // GenerateToken 生成JWT令牌 func GenerateToken(user *models.User, cfg *config.JWTConfig) (string, error) { claims := JWTClaims{ UserID: user.ID, Username: user.Username, IsAdmin: user.IsAdmin, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(cfg.ExpireHour) * time.Hour)), IssuedAt: jwt.NewNumericDate(time.Now()), Issuer: "ezops", }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(cfg.Secret)) } // JWTAuth JWT认证中间件 func JWTAuth(cfg *config.JWTConfig) gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, models.Response{ Code: 401, Message: "未提供认证令牌", }) c.Abort() return } parts := strings.SplitN(authHeader, " ", 2) if !(len(parts) == 2 && parts[0] == "Bearer") { c.JSON(http.StatusUnauthorized, models.Response{ Code: 401, Message: "认证令牌格式错误", }) c.Abort() return } tokenString := parts[1] token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(cfg.Secret), nil }) if err != nil { c.JSON(http.StatusUnauthorized, models.Response{ Code: 401, Message: "无效的认证令牌: " + err.Error(), }) c.Abort() return } if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid { c.Set("userID", claims.UserID) c.Set("username", claims.Username) c.Set("isAdmin", claims.IsAdmin) c.Next() } else { c.JSON(http.StatusUnauthorized, models.Response{ Code: 401, Message: "无效的认证令牌", }) c.Abort() } } } // AdminAuth 管理员认证中间件 func AdminAuth() gin.HandlerFunc { return func(c *gin.Context) { isAdmin, exists := c.Get("isAdmin") if !exists || !isAdmin.(bool) { c.JSON(http.StatusForbidden, models.Response{ Code: 403, Message: "需要管理员权限", }) c.Abort() return } c.Next() } } // GetUserID 获取当前用户ID func GetUserID(c *gin.Context) uint { userID, exists := c.Get("userID") if !exists { return 0 } return userID.(uint) } // GetUsername 获取当前用户名 func GetUsername(c *gin.Context) string { username, exists := c.Get("username") if !exists { return "" } return username.(string) } // GetIsAdmin 获取是否为管理员 func GetIsAdmin(c *gin.Context) bool { isAdmin, exists := c.Get("isAdmin") if !exists { return false } return isAdmin.(bool) }