路由中间件必须直接挂载在对应路由方法(如app.Get)的参数中,而非用app.Use全局注册;正确顺序为authMW→logMW→handler,且仅对指定路径生效,错误注册会导致无关接口被拦截。

路由中间件必须用 app.Get、app.Post 等方法直接挂载
全局中间件(app.Use)不适用于单一路由控制——它对所有匹配前缀的请求无差别生效,没法区分 /login 和 /admin/users。真要给某条路由加专属逻辑(比如只对 /api/user 做鉴权),必须把中间件函数写在对应路由注册调用的参数列表里。
常见错误是把 authMW 写成 app.Use(authMW) 后发现连 /health 都被拦了。这不是中间件写得不对,而是注册位置错了。
-
app.Get("/api/user", authMW, logMW, handler):执行顺序为 authMW → logMW → handler,且仅此路径生效 - 多个中间件按书写顺序依次执行,
authMW必须在logMW前面,否则鉴权失败时日志可能漏打 - 中间件函数内若校验失败,直接
return c.Status(401).SendString("unauthorized"),千万别调c.Next() - 不要在路由中间件里重复处理响应头或 body,Fiber 不会自动跳过后续中间件——没
return就继续往下走
app.Group 是批量绑定路由中间件的正确方式
当一组路由共用同一套前置逻辑(如所有 /api/xxx 接口都要鉴权+限流),别一个个手写中间件参数。用 app.Group 创建子路由组,再把中间件传进去,更清晰也更安全。
注意:app.Group 本身不注册任何 handler,它只是个“中间件容器”,最终仍需在返回的 group 实例上调用 Get、Post 等方法。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
-
api := app.Group("/api", authMW, rateLimitMW)→ 此后api.Get("/user", handler)的完整链是:全局中间件 →authMW→rateLimitMW→handler -
app.Group的中间件只影响该 group 下注册的路由,不会污染/health或/favicon.ico - 不能把
app.Group("/api", fiber.BasicAuth())当成“自动保护”,BasicAuth 中间件仍需你手动判断并返回 401,否则无效 - 如果 group 嵌套过深(比如
app.Group("/v1").Group("/api")),路径拼接容易出错,建议扁平化设计
别混淆 app.Use 和路由中间件的执行时机
app.Use 注册的中间件永远在路由级中间件之前执行;反过来,路由级中间件永远在 app.Use 之后、handler 之前执行。这个顺序是硬编码进 Fiber 路由器的,改不了。
一个典型陷阱:你在 app.Use(loggerMW) 后面又写了 app.Use(recoverMW),但 recoverMW 没捕获到 panic,因为 loggerMW 里某个地方提前 panic 了,而 recoverMW 还没轮到执行。
- 想让 recoverMW 生效,它必须比所有可能 panic 的中间件更靠前,比如放在第一个
app.Use - 日志中间件想记录完整生命周期(进入 + 退出),必须是第一个
app.Use,否则 handler panic 后它收不到“退出”信号 - 路由组
api := app.Group("/api", m1)和app.Use(m0)是正交的,但执行时严格按代码顺序叠加:m0 → m1 → handler - 如果同时用了
app.Use("/api", corsMW)和app.Group("/api", authMW),前者会先于后者执行,且作用范围更宽(包括/api/xxx所有子路径)
中间件函数签名和返回值必须严格匹配
Fiber 对中间件函数签名极其敏感:必须是 func(*fiber.Ctx) error,且必须显式 return。少一个 return,handler 就永远不会执行;多一个 c.Next() 在拒绝逻辑里,就会导致未授权请求照样穿透。
最常踩的坑是复制粘贴中间件模板后忘了改返回值,或者误以为 “调了 c.Send() 就自动终止”,其实 Fiber 只看函数是否返回了 error 或 nil,不看内部有没有写响应。
- 正确写法:
return c.Status(403).SendString("forbidden") - 错误写法:
c.Status(403).SendString("forbidden"); return nil—— handler 仍会执行 - 错误写法:
if !valid { c.Status(401).Send(); c.Next(); return }——c.Next()强制继续,认证形同虚设 - 所有中间件都应以
err := c.Next()开头(如需继续),然后根据 err 做后续处理,最后统一return err
return,整个认证链就失效;注册位置差一个位置,健康检查接口就不可用。


















