全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 6 分钟 ✍️ juanwangdev

全局中间件与路由组中间件

中间件可以全局注册,也可以限定在特定路由组,灵活控制请求处理范围。

全局中间件

使用 r.Use() 注册,作用于所有路由:

Go
func main() {
    r := gin.New()

    // 全局注册
    r.Use(loggerMiddleware())
    r.Use(corsMiddleware())

    // 所有路由都会经过这些中间件
    r.GET("/api/users", listUsers)
    r.GET("/api/products", listProducts)
    r.GET("/health", healthCheck) // 也经过全局中间件

    r.Run(":8080")
}

路由组中间件

使用 group.Use() 注册,仅作用于组内路由:

Go
func main() {
    r := gin.New()

    // 全局中间件
    r.Use(loggerMiddleware())

    // 需认证的 API 组
    authGroup := r.Group("/api")
    authGroup.Use(authMiddleware())
    {
        authGroup.GET("/users", listUsers)
        authGroup.GET("/profile", getProfile)
    }

    // 公开 API,不需要认证
    publicGroup := r.Group("/public")
    // 不添加认证中间件
    {
        publicGroup.GET("/info", getInfo)
        publicGroup.GET("/health", healthCheck)
    }

    r.Run(":8080")
}

单路由中间件

直接在路由注册时添加:

Go
func main() {
    r := gin.New()

    // 单路由添加中间件
    r.GET("/admin", authMiddleware(), roleMiddleware("admin"), adminHandler)

    // 多个中间件按顺序执行
    r.DELETE("/user/:id",
        authMiddleware(),
        permissionMiddleware("delete_user"),
        deleteUserHandler,
    )

    r.Run(":8080")
}

中间件执行顺序

Go
func main() {
    r := gin.New()

    // 全局中间件
    r.Use(middlewareA())
    r.Use(middlewareB())

    // 路由组中间件
    api := r.Group("/api")
    api.Use(middlewareC())
    api.Use(middlewareD())

    api.GET("/test", middlewareE(), handler)

    // 执行顺序:A → B → C → D → E → Handler → E → D → C → B → A
}

嵌套路由组

Go
func main() {
    r := gin.New()

    r.Use(loggerMiddleware())

    api := r.Group("/api")
    api.Use(authMiddleware())

    // 嵌套子组
    admin := api.Group("/admin")
    admin.Use(roleMiddleware("admin"))
    {
        admin.GET("/users", listAdminUsers)
        admin.DELETE("/user/:id", deleteUser)
    }

    // 普通用户组
    user := api.Group("/user")
    {
        user.GET("/profile", getProfile)
    }

    // 执行顺序:
    // /api/admin/users: logger → auth → role → handler
    // /api/user/profile: logger → auth → handler
}

中间件适用范围对比

注册方式适用范围方法
全局中间件所有路由r.Use()
路由组中间件组内所有路由group.Use()
单路由中间件单个路由路义时添加

排除特定路由

Go
func skipAuthMiddleware() gin.HandlerFunc {
    skipPaths := []string{"/health", "/metrics", "/login"}

    return func(c *gin.Context) {
        path := c.Request.URL.Path
        for _, skip := range skipPaths {
            if path == skip {
                c.Next()
                return
            }
        }

        // 其他路径检查认证
        if !isAuthenticated(c) {
            c.AbortWithStatus(401)
            return
        }
        c.Next()
    }
}

最佳实践配置

Go
func main() {
    r := gin.New()

    // 1. 全局基础中间件
    r.Use(gin.Recovery())
    r.Use(loggerMiddleware())
    r.Use(corsMiddleware())

    // 2. 公开路由
    r.GET("/health", healthCheck)
    r.GET("/metrics", metricsHandler)
    r.POST("/login", loginHandler)

    // 3. 需认证的 API
    api := r.Group("/api/v1")
    api.Use(authMiddleware())
    {
        api.GET("/users", listUsers)
        api.GET("/profile", getProfile)
    }

    // 4. 管理员 API
    admin := api.Group("/admin")
    admin.Use(roleMiddleware("admin"))
    {
        admin.DELETE("/users/:id", deleteUser)
        admin.POST("/config", updateConfig)
    }

    r.Run(":8080")
}

执行流程图

text
请求
  ↓
全局中间件 (r.Use)
  ↓
路由组中间件 (group.Use)
  ↓
路由中间件 (路由注册时)
  ↓
处理函数
  ↓
逆向返回

全局中间件放基础功能,认证等业务中间件放路由组。

要点总结

  • r.Use() 注册全局中间件,作用于所有路由
  • group.Use() 注册路由组中间件,仅作用于组内路由
  • 单路由可直接在路由注册时添加中间件
  • 中间件按注册顺序执行,形成洋葱结构
  • 合理分组可避免不必要的中间件执行

📝 发现内容有误?点击此处直接编辑

← 上一篇 中间件错误处理
下一篇 → 第三方中间件集成
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库