package middleware import ( "os" "strings" "github.com/gofiber/fiber/v2" "github.com/golang-jwt/jwt/v5" ) type JWTClaims struct { UserID string `json:"user_id"` Email string `json:"email"` jwt.RegisteredClaims } func Protected() fiber.Handler { return func(c *fiber.Ctx) error { authHeader := c.Get("Authorization") if authHeader == "" { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization header"}) } parts := strings.SplitN(authHeader, " ", 2) if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid authorization header format"}) } tokenStr := parts[1] secret := os.Getenv("JWT_SECRET") if secret == "" { secret = "changeme-jwt-secret" } claims := &JWTClaims{} token, err := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) { if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fiber.ErrUnauthorized } return []byte(secret), nil }) if err != nil || !token.Valid { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid or expired token"}) } c.Locals("user_id", claims.UserID) c.Locals("user_email", claims.Email) return c.Next() } }