BasicAuth中间件默认仅支持单组凭证,因其底层使用map[string]string进行精确匹配;可通过自定义中间件函数或传入validator闭包实现多组凭据校验,但必须启用HTTPS并正确设置WWW-Authenticate等响应头。

BasicAuth中间件默认只支持单组凭证
Fiber 的 fiber.Handler 类型中间件 middleware.BasicAuth 底层调用的是 fiber.New().Use(middleware.BasicAuth(...)),它接受一个 map[string]string 参数,键是用户名、值是密码。这个结构天然不支持「同一中间件实例校验多组账号密码」——因为 map 查找是精确匹配,无法做多对一或条件判断。
用自定义函数替代内置 BasicAuth
直接传入一个匿名函数作为中间件,绕过内置限制,手动解析 Authorization 头并比对多组凭据:
app.Use(func(c *fiber.Ctx) error {
auth := c.Get("Authorization")
if auth == "" {
return c.Status(fiber.StatusUnauthorized).SendString("Missing Authorization header")
}
// 解析 Basic 认证头:Basic base64(user:pass)
if !strings.HasPrefix(auth, "Basic ") {
return c.Status(fiber.StatusUnauthorized).SendString("Invalid auth scheme")
}
decoded, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
if err != nil {
return c.Status(fiber.StatusUnauthorized).SendString("Invalid base64 in auth header")
}
pair := strings.SplitN(string(decoded), ":", 2)
if len(pair) != 2 {
return c.Status(fiber.StatusUnauthorized).SendString("Invalid credentials format")
}
user, pass := strings.TrimSpace(pair[0]), strings.TrimSpace(pair[1])
// 手动比对多组账号密码(可从 DB、env 或 config 加载)
validCreds := map[string]string{
"admin": "p@ssw0rd",
"apiuser": "secret123",
"monitor": "health-check-2026",
}
if expectedPass, ok := validCreds[user]; ok && pass == expectedPass {
return c.Next()
}
return c.Status(fiber.StatusUnauthorized).SendString("Invalid username or password")
})
- 不要硬编码密码,生产环境应从
os.Getenv或配置中心加载 - 注意
strings.TrimSpace,避免前后空格导致比对失败 - 如果凭据量大(如上百组),建议改用
sync.Map或查数据库,避免每次请求遍历 map
用 middleware.BasicAuth + 自定义 validator 实现复用
如果你仍想复用 Fiber 提供的 middleware.BasicAuth 结构,可以传入一个闭包函数作为 validator,它接收 username 和 password,返回布尔值:
validUsers := map[string]string{
"dev": "dev123",
"qa": "test456",
}
authMiddleware := middleware.BasicAuth(func(username, password string) bool {
expected, ok := validUsers[username]
return ok && password == expected
})
app.Use(authMiddleware)
- 这个写法比纯自定义中间件更简洁,且保留了 Fiber 内置的错误响应逻辑(如自动返回 401)
- 注意:
middleware.BasicAuth会自动处理 header 解析和 base64 解码,你只需专注验证逻辑 - 该函数在每次请求中被调用,避免全局变量状态污染
常见踩坑点:明文密码、跨域与缓存
Basic Auth 本身不加密,所有凭证以 base64 编码明文传输,必须配合 HTTPS 使用,否则账号密码会被中间人截获。
- 若前端是浏览器应用,需确保后端响应包含
Access-Control-Allow-Headers: Authorization,否则预检请求会失败 - 某些代理或 CDN 会缓存 401 响应,导致后续正确凭据也被拒绝;可在响应头加
Cache-Control: no-cache, no-store - Fiber 默认不设置
WWW-Authenticate头,但浏览器需要它才能弹出登录框;可手动加:c.Set("WWW-Authenticate", `Basic realm="Restricted"`)
多组账号密码本身不增加复杂度,真正容易被忽略的是传输安全和响应头细节——没配 HTTPS 或漏掉 WWW-Authenticate,整个认证流程就卡在第一步。


















