Fiber v3 的 basicauth 中间件必须用 basicauth.UsernameFromContext(c) 获取用户名,不再写入 c.Locals();需显式配置非空 Users 映射、按路径分组启用,并强制 HTTPS 保障传输安全。

Fiber v3 的 basicauth 中间件必须用 basicauth.UsernameFromContext 取用户名
从 Fiber v3 开始,basicauth 中间件不再把认证信息写入 c.Locals(),而是存进 context 的私有键里。直接写 c.Locals("username") 或 c.Locals("user") 会返回 nil,且不报错——这是最常踩的静默坑。
正确做法是导入 github.com/gofiber/fiber/v2/middleware/basicauth 后,用它导出的 UsernameFromContext 函数:
import "github.com/gofiber/fiber/v2/middleware/basicauth"
func handler(c *fiber.Ctx) error {
username := basicauth.UsernameFromContext(c.Context())
if username == "" {
return c.Status(fiber.StatusUnauthorized).SendString("no auth")
}
return c.JSON(map[string]string{"user": username})
}
- 该函数接受
*fiber.Ctx、fiber.CustomCtx或原生context.Context,兼容性好 - 如果认证失败或未触发中间件,
UsernameFromContext返回空字符串,不是 panic - 密码不会暴露在任何 API 中——Fiber v3 不提供取密码的方法,也不应取
配置 basicauth.New 时必须传 Users 映射,不能留空
basicauth.New 默认不启用任何用户校验,传空 map[string]string{} 或完全不配 Users 字段,会导致所有请求都通过(等价于没开认证)。
常见错误配置:
// ❌ 错误:没设 Users,中间件形同虚设
app.Use(basicauth.New())
// ❌ 错误:Users 是空 map
app.Use(basicauth.New(basicauth.Config{
Users: map[string]string{},
}))
// ✅ 正确:显式声明至少一个账号
app.Use(basicauth.New(basicauth.Config{
Users: map[string]string{
"admin": "s3cr3t!",
"viewer": "ro-only",
},
}))
-
Users是唯一必需字段;其他如Realm、Authorizer都可选 - 密码明文存在代码里只适合本地调试;生产环境建议用
viper加载 YAML 文件,并设文件权限为600 - 不要用
os.Getenv直读密码——进程内存和/proc/$PID/environ都能直接看到
Basic Auth 必须配合 Group 使用,否则路由无法受保护
很多人把 basicauth.New 当成全局中间件挂到 app.Use(),结果发现 /admin 和 /public 全部 401。原因在于:Fiber 的 basicauth 中间件默认对所有路径生效,但它的 401 响应逻辑依赖于 WWW-Authenticate 头,而这个头只在认证失败且路由匹配时才写入。如果没分组,中间件会拦截每个请求,包括静态资源、健康检查等,造成误拦。
推荐做法是按路径分组保护:
// ✅ 只对 /api/admin 下的路由启用 Basic Auth
admin := app.Group("/api/admin")
admin.Use(basicauth.New(basicauth.Config{
Users: map[string]string{"admin": "p@ssw0rd"},
}))
admin.Get("/secrets", func(c *fiber.Ctx) error {
return c.JSON(map[string]string{"data": "sensitive"})
})
- 不要用
app.Use(basicauth.New(...))全局启用,除非你真想整个服务都强制认证 - 若需混合策略(部分路由要认证,部分不要),必须用
Group切分,而不是靠中间件内部条件判断 - 浏览器访问时,第一次 401 后弹窗输错一次,再输对仍 401?大概率是路由没走对 Group,检查
app.Group的前缀是否和请求路径完全匹配
HTTPS 是硬性前提,HTTP 下 Basic Auth 等于裸奔
Authorization 头里的凭据是 Base64 编码,不是加密——Base64 可逆,抓个包就能还原出明文用户名密码。Fiber 的 basicauth 中间件本身不处理传输层安全,它只做应用层校验。
如果你还在 HTTP 上跑 Basic Auth:
- 内网调试可以接受,但得确保网络边界可控(比如 Docker bridge 网络、K8s Pod 内部)
- 任何暴露在公网或跨网段的场景,必须配 HTTPS;Traefik/Nginx 前置终止 TLS 是常见方案
- Fiber 自带的 HTTPS 启动方式(
app.ListenTLS)仅适合测试,证书管理请交由反向代理
真正容易被忽略的是:哪怕你用了 HTTPS,如果客户端(比如 curl 或前端 fetch)没发正确的 Authorization 头,或者服务端响应没带 WWW-Authenticate,浏览器就不会弹登录框——这时你会卡在“没反应”,而不是 401。检查响应头是否含 WWW-Authenticate: Basic realm="Restricted",这是触发浏览器认证流程的关键。


















