Gin 中间件指南

Gin 中间件模式:内置 Recovery 和 Logger、CORS 设置、JWT 认证、限流和上下文数据传递。

1. 内置中间件

r := gin.Default() // = gin.New() + Logger + Recovery

// 自定义日志格式
r.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
    return fmt.Sprintf("[%s] %s %s %d %s\n",
        param.TimeStamp.Format(time.RFC3339),
        param.Method, param.Path, param.StatusCode, param.Latency,
    )
}))

2. 自定义中间件

func RequestID() gin.HandlerFunc {
    return func(c *gin.Context) {
        id := c.GetHeader("X-Request-ID")
        if id == "" {
            id = uuid.New().String()
        }
        c.Set("requestID", id)
        c.Header("X-Request-ID", id)
        c.Next()
    }
}

r.Use(RequestID())

3. JWT 认证中间件

func JWTAuth(secret string) gin.HandlerFunc {
    return func(c *gin.Context) {
        authHeader := c.GetHeader("Authorization")
        if !strings.HasPrefix(authHeader, "Bearer ") {
            c.AbortWithStatusJSON(401, gin.H{"error": "缺少 token"})
            return
        }
        tokenStr := strings.TrimPrefix(authHeader, "Bearer ")
        claims := &Claims{}
        token, err := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) {
            return []byte(secret), nil
        })
        if err != nil || !token.Valid {
            c.AbortWithStatusJSON(401, gin.H{"error": "token 无效"})
            return
        }
        c.Set("userID", claims.UserID)
        c.Next()
    }
}

4. CORS 中间件

r.Use(cors.New(cors.Config{
    AllowOrigins:     []string{"https://app.example.com"},
    AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
    AllowHeaders:     []string{"Authorization", "Content-Type"},
    AllowCredentials: true,
    MaxAge:           12 * time.Hour,
}))