Fiber中间件是签名必须为func(*fiber.Ctx) error的函数,用于处理横切关注点;它与普通函数无类型区别,但必须正确调用c.Next()或显式return响应才能控制流程,否则请求会卡住。

什么是 Fiber 的中间件,它和普通函数有什么区别
Fiber 的中间件本质是一个接收 fiber.Ctx 参数、返回 error 的函数,签名必须是 func(c *fiber.Ctx) error。它不是任意函数——如果漏写 return c.Next() 或提前 return nil 但没终止流程,请求就会卡住或跳过后续中间件。
常见错误现象包括:
- 接口响应空白,无日志也无报错(大概率忘了调用
c.Next()) - 路由处理器完全没执行(中间件里写了
c.Status(401).SendString("no")却没加return) - 多个中间件串行时顺序错乱(注册顺序 ≠ 执行顺序,Fiber 是从左到右依次注册、从外到内嵌套执行)
使用场景上,中间件适合做统一鉴权、日志记录、跨域头注入、请求体预处理等与业务逻辑解耦的横切关注点。
如何编写一个带参数的自定义中间件(比如 JWT 验证)
Fiber 不支持直接传参给中间件函数,必须用闭包封装参数。例如验证 JWT 时需要指定密钥和签发方,就得写成函数返回函数的形式:
立即学习“go语言免费学习笔记(深入)”;
func JWTAuth(secret string, issuer string) fiber.Handler {
return func(c *fiber.Ctx) error {
token := c.Get("Authorization")
if token == "" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "missing token"})
}
// ……解析并校验逻辑
if valid {
c.Locals("user_id", userID) // 写入上下文供后续 handler 使用
return c.Next() // 继续链路
}
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "invalid token"})
}
}关键点:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 必须返回
fiber.Handler类型(即func(*fiber.Ctx) error) - 参数在闭包外层捕获,不能靠全局变量传配置(并发不安全)
-
c.Locals是线程安全的 ctx 级存储,比全局 map 或指针传参更可靠
中间件里怎么正确中断请求而不 panic
Fiber 中断请求靠的是「提前 return 错误或响应」,但必须注意:
-
c.SendStatus(403)本身不终止链路,得搭配return -
c.JSON(...)/c.SendString(...)也不自动终止,漏掉return就会继续执行后续中间件甚至路由 handler - 如果用了
c.Redirect或c.Attachment,同样要return,否则可能触发 “body written after headers sent” 错误
典型写法:
if !isValidIP(c.IP()) {
c.Status(fiber.StatusForbidden)
return c.SendString("blocked") // ✅ 正确:有 return
}
// ❌ 错误示例(下面这行还会执行):
// c.SendString("blocked")另外,不要在中间件里 recover panic——Fiber 自带 panic 捕获机制,手动 recover 反而可能干扰错误日志和 fiber.Error 处理流程。
为什么自定义中间件注册后没生效
最常见原因是注册位置不对:
-
app.Use(middleware)是全局中间件,对所有路由生效(包括静态文件) -
app.Get("/api/user", middleware, handler)是局部中间件,只对该路由起作用 - 如果你写了
app.Get("/user", handler, middleware),那中间件根本不会运行——顺序错了,handler 在前就直接执行了
还有几个隐蔽坑:
- 中间件函数名首字母小写 + 没导出(比如
auth()),导致其他包无法引用 - 使用了
app.All("*", ...)但没加app.Static之前,静态资源被中间件拦截(比如 favicon.ico 触发鉴权失败) - 在中间件里修改了
c.Request().URI().SetPath()却没调用c.Route()刷新路由匹配,导致后续 handler 找不到对应路由
Fiber 的中间件链是同步执行、不可跳过的,一旦某个环节没 return 也没调 c.Next(),整个请求生命周期就挂住了——这点比 Express 更严格,也更容易踩空。

















