token校验中间件必须在路由注册前挂载,即先app.use(jwtmiddleware),再app.get()等定义路由,否则不生效;推荐用group隔离受保护路径,避免硬编码路径判断。

Token校验中间件必须在路由注册前挂载
中间件在 Fiber 中是链式执行的,如果 app.Use() 放在 app.Get() 等路由定义之后,该中间件对这些路由完全不生效。这是最常踩的坑——写完了逻辑却始终没触发校验。
正确顺序是:初始化 app → 注册全局中间件(如日志、恢复、Token 校验)→ 再注册路由。Token 校验中间件通常应放在 fiber.New() 后立即挂载,除非你明确只需要保护部分路由组。
示例:
app := fiber.New()
app.Use(jwtMiddleware) // ✅ 必须放这里
app.Get("/profile", handler) // ✅ 才会被拦截
// app.Get("/login", loginHandler) // 可单独跳过,见下节
如何跳过登录接口等免校验路径
Fiber 中间件默认作用于所有请求,但登录、注册、健康检查等接口不能强制校验 Token。直接在中间件里写 if 判断路径容易漏掉方法或前缀,更可靠的方式是用 app.Group() 隔离,并只对受保护的分组应用中间件。
- 用
api := app.Group("/api")创建受保护的路由前缀 - 对
api调用.Use(jwtMiddleware),其下所有子路由自动继承 - 登录接口走根路径或独立 group,如
app.Post("/login", loginHandler),完全绕过中间件
避免在中间件函数内部硬编码路径判断,否则后续加新接口或改 path 时极易遗漏或出错。
解析 JWT 失败时要明确返回 HTTP 状态和错误结构
常见错误是解析失败后直接 return c.Next() 或 panic,导致前端收到 500 或空响应。Fiber 中间件应主动终止流程并返回标准错误体。
关键点:
- 调用
c.Status(401).JSON()或c.Status(403).JSON()明确状态码 - 不要用
c.SendString()返回纯文本,前后端约定应为 JSON 格式,如{"error": "invalid token"} - 注意
jwt.Parse()的 error 类型:如果是jwt.ErrSignatureInvalid或jwt.ErrTokenExpired,应分别返回 401 和 401(或 403),便于前端区分处理
示例片段:
if err != nil {
if errors.Is(err, jwt.ErrTokenExpired) {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "token expired"})
}
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid token"})
}
从 Authorization Header 提取 Token 的细节陷阱
Fiber 的 c.Get("Authorization") 返回的是完整 header 值,比如 "Bearer eyJhbGciOi...",不能直接传给 jwt.Parse()。必须手动切掉前缀,且要考虑大小写和空格。
推荐写法:
- 用
strings.TrimSpace()清除首尾空格 - 用
strings.HasPrefix(auth, "Bearer ")判断(注意 Bearer 后是空格,不是下划线或冒号) - 提取时用
auth[7:],而非strings.Split(auth, " ")[1],避免多空格或异常格式崩溃 - 若 header 不存在,应直接返回 401,不要继续解析空字符串
这个步骤出错会导致 “token is empty” 或 “illegal base64” 错误,但实际只是提取逻辑没写对。
Fiber 的中间件机制本身很轻量,但 Token 校验涉及 header 解析、JWT 验签、错误分类、路径控制多个环节,任一环节松动都会让认证形同虚设。尤其要注意 header 提取和中间件挂载时机这两个地方,线上环境出问题时最难排查。











