package middleware import ( "net/http" "strings" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" "github.com/wangjia/jiu/backend/config" ) type Claims struct { UserID uint64 `json:"user_id"` HotelID uint64 `json:"hotel_id"` Role string `json:"role"` jwt.RegisteredClaims } const ( CtxUserID = "user_id" CtxHotelID = "hotel_id" CtxRole = "role" ) func JWT() gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") { c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "missing token"}) return } tokenStr := strings.TrimPrefix(authHeader, "Bearer ") claims := &Claims{} token, err := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) { return []byte(config.C.JWT.Secret), nil }) if err != nil || !token.Valid { c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"}) return } c.Set(CtxUserID, claims.UserID) c.Set(CtxHotelID, claims.HotelID) c.Set(CtxRole, claims.Role) c.Next() } } // AdminOnly 仅管理员可访问 func AdminOnly() gin.HandlerFunc { return func(c *gin.Context) { role, _ := c.Get(CtxRole) if role != "admin" { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "admin only"}) return } c.Next() } } // GetHotelID 从 context 中安全获取 hotel_id func GetHotelID(c *gin.Context) uint64 { v, _ := c.Get(CtxHotelID) id, _ := v.(uint64) return id } // GetUserID 从 context 中安全获取 user_id func GetUserID(c *gin.Context) uint64 { v, _ := c.Get(CtxUserID) id, _ := v.(uint64) return id }