middleware

package
v0.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2026 License: MIT Imports: 11 Imported by: 0

README

Middleware

Colección de middlewares listos para usar con Gin, integrados con el logger y security de gokit.

📦 Instalación

go get github.com/AndresGT/gokit/middleware

🔐 Auth Middleware (JWT)

Middleware de autenticación JWT con logging de seguridad y soporte de roles.

Uso Básico
import (
    "github.com/AndresGT/gokit/middleware"
    "github.com/AndresGT/gokit/security/jwt"
)

// Configurar JWT
jwt.Configure(jwt.Config{
    Secret: "tu-secreto",
})

router := gin.New()

router.Use(middleware.Auth(middleware.AuthConfig{
    SkipPaths: []string{"/login", "/register", "/health"},
}))
Configuración Completa
router.Use(middleware.Auth(middleware.AuthConfig{
    Secret: "tu-secreto",
    SkipPaths: []string{"/api/public"},
    Logger: myLogger,
    TokenExtractor: middleware.HeaderOnlyExtractor,
    ErrorHandler: func(c *gin.Context, err error) {
        c.JSON(401, gin.H{"error": err.Error()})
    },
}))
Helpers en Handlers
func myHandler(c *gin.Context) {
    userID, _ := middleware.GetUserID(c)
    userUUID, _ := middleware.GetUserUUID(c)
    role, _ := middleware.GetUserRole(c)
    claims, _ := middleware.GetClaims(c)
}
Requerir Roles
admin := router.Group("/admin")
admin.Use(middleware.RequireRole("admin", "superadmin"))
{
    admin.GET("/users", listUsers)
}

🌐 CORS Middleware

Manejo flexible de CORS.

Desarrollo
router.Use(middleware.DefaultCORS())
Producción
router.Use(middleware.CORS(middleware.ProductionCORSConfig([]string{
    "https://miapp.com",
})))
Configuración Personalizada
router.Use(middleware.CORS(middleware.CORSConfig{
    AllowOrigins: []string{"https://miapp.com"},
    AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
    AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
    AllowCredentials: true,
    MaxAge: 3600,
}))

🛡️ Recovery Middleware

Recupera panics con logging estructurado.

Desarrollo
router.Use(middleware.DefaultRecovery())
Producción
router.Use(middleware.ProductionRecovery())
Personalizado
router.Use(middleware.Recovery(middleware.RecoveryConfig{
    Logger: myLogger,
    EnableStackTrace: true,
    RecoveryHandler: func(c *gin.Context, err interface{}) {
        c.JSON(500, gin.H{"error": "internal error"})
    },
}))

🆔 Request ID Middleware

Asigna un ID único a cada request y lo integra con el logger.

Uso Básico
router.Use(middleware.DefaultRequestID())
Modo Estricto (ignora request_id entrante)
router.Use(middleware.StrictRequestID())
Personalizado
router.Use(middleware.RequestID(middleware.RequestIDConfig{
    Header: "X-Request-ID",
    TrustIncoming: true,
    InjectToLogger: true,
}))
Obtener Request ID
func handler(c *gin.Context) {
    requestID := middleware.GetRequestID(c)
    logger.WithFields(logger.Fields{
        "request_id": requestID,
    }).Info("Processing request")
}

🎯 Stack Completo Recomendado

router := gin.New()

router.Use(middleware.DefaultRequestID())                 // 1. Request ID
router.Use(logger.GinMiddlewareWithFields(appLogger))     // 2. Logger
router.Use(middleware.DefaultRecovery())                  // 3. Recovery
router.Use(middleware.DefaultCORS())                      // 4. CORS
router.Use(middleware.Auth(middleware.AuthConfig{}))      // 5. Auth

💡 Buenas Prácticas

Orden de Middlewares
  1. RequestID
  2. Logger
  3. Recovery
  4. CORS
  5. Auth
CORS Seguro en Producción
AllowOrigins: []string{"https://miapp.com"}
AllowCredentials: true
Rutas Públicas vs Protegidas
router.Use(middleware.Auth(middleware.AuthConfig{
    SkipPaths: []string{"/api/public", "/health"},
}))

🧪 Testing

func TestProtectedEndpoint(t *testing.T) {
    router := gin.New()
    router.Use(middleware.Auth(middleware.AuthConfig{
        Secret: "test-secret",
    }))

    token, _ := jwt.Generate(uuid.New(), "user")

    req := httptest.NewRequest("GET", "/api/profile", nil)
    req.Header.Set("Authorization", "Bearer "+token)

    w := httptest.NewRecorder()
    router.ServeHTTP(w, req)

    assert.Equal(t, 200, w.Code)
}


Parte de gokit — Toolkit de Go para desarrollo rápido.

Documentation

Index

Constants

View Source
const (
	RequestIDKey    = "request_id"
	RequestIDHeader = "X-Request-ID"
)

Variables

View Source
var (
	ErrNoToken       = errors.New("auth: token not provided")
	ErrInvalidToken  = errors.New("auth: invalid or expired token")
	ErrInvalidClaims = errors.New("auth: invalid claims")
)

Functions

func Auth

func Auth(cfg AuthConfig) gin.HandlerFunc

func CORS

func CORS(cfg CORSConfig) gin.HandlerFunc

func CookieOnlyExtractor

func CookieOnlyExtractor(c *gin.Context) string

func DefaultCORS

func DefaultCORS() gin.HandlerFunc

Default middleware

func DefaultGenerator

func DefaultGenerator() string

func DefaultRecovery

func DefaultRecovery() gin.HandlerFunc

DefaultRecovery modo desarrollo

func DefaultRequestID

func DefaultRequestID() gin.HandlerFunc

DefaultRequestID modo estándar

func DefaultTokenExtractor

func DefaultTokenExtractor(c *gin.Context) string

func DefaultValidator

func DefaultValidator(id string) bool

func GetClaims

func GetClaims(c *gin.Context) (*jwt.Claims, bool)

func GetRequestID

func GetRequestID(c *gin.Context) string

func GetUserID

func GetUserID(c *gin.Context) (uuid.UUID, bool)

func GetUserRole

func GetUserRole(c *gin.Context) (string, bool)

func HeaderOnlyExtractor

func HeaderOnlyExtractor(c *gin.Context) string

func ProductionRecovery

func ProductionRecovery() gin.HandlerFunc

ProductionRecovery modo producción

func Recovery

func Recovery(cfg RecoveryConfig) gin.HandlerFunc

func RequestID

func RequestID(cfg RequestIDConfig) gin.HandlerFunc

func RequireRole

func RequireRole(roles ...string) gin.HandlerFunc

func StrictRequestID

func StrictRequestID() gin.HandlerFunc

StrictRequestID ignora request_id entrante

Types

type AuthConfig

type AuthConfig struct {
	SkipPaths []string

	ErrorHandler func(c *gin.Context, err error)

	Logger *logger.Logger

	TokenExtractor func(*gin.Context) string
}

type CORSConfig

type CORSConfig struct {
	AllowOrigins     []string
	AllowMethods     []string
	AllowHeaders     []string
	ExposeHeaders    []string
	AllowCredentials bool
	MaxAge           int
}

func DefaultCORSConfig

func DefaultCORSConfig() CORSConfig

Config por defecto (dev-friendly)

func ProductionCORSConfig

func ProductionCORSConfig(origins []string) CORSConfig

Config segura para producción

type RecoveryConfig

type RecoveryConfig struct {
	Logger *logger.Logger

	// Handler custom para panic
	RecoveryHandler func(c *gin.Context, err any)

	// Mostrar stack trace en logs
	EnableStackTrace bool

	// Mostrar detalles en respuesta HTTP (solo dev)
	ExposeError bool

	// Status HTTP en panic
	StatusCode int
}

type RequestIDConfig

type RequestIDConfig struct {
	Header string

	// Generador de ID
	Generator func() string

	// Validador del ID entrante
	Validator func(string) bool

	// Confiar en request_id entrante (si false, siempre genera uno nuevo)
	TrustIncoming bool

	// Inyectar automáticamente en logger
	InjectToLogger bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL