核心是用c.IP()判断是否在黑名单map[string]struct{}中,命中则return c.Status(403).SendString("Forbidden")且不调c.Next();需配置ProxyHeader解决代理IP问题,路径拦截用strings.HasPrefix(c.Path(), "/api/"),白名单匹配成功应return c.Next()。

怎么用中间件拦截黑名单 IP 并立即拒绝
直接 return 403,不调 c.Next(),否则请求照常进 handler。Fiber 不会自动中断流程,漏掉 return 就等于放行。
常见错误现象:IP 在黑名单里,但请求仍进到 handler;或返回 200 却没内容——本质是写了判断逻辑但忘了 return c.Status(403).SendString("Forbidden")。
- 黑名单建议用
map[string]struct{}(单机)或sync.Map(并发安全),别遍历切片 - 别直接读
c.Get("X-Forwarded-For")——它可被伪造;若前端有可信反向代理(如 Nginx),应先配置app.Config().ProxyHeader = "X-Real-IP",再用c.IP()获取真实客户端 IP - 本地测试时注意:
c.IP()通常是127.0.0.1,不是你预期的“公网 IP” - 如需支持 CIDR 段(如
192.168.1.0/24),用标准库net.ParseCIDR+ipNet.Contains(),别手写字符串匹配
怎么让黑白名单只对 /api/** 路径生效
路径判断必须写在中间件最前面,用 strings.HasPrefix(c.Path(), "/api/"),轻量且无编译开销。别用 c.Route().Path——它返回的是路由定义模板(如 /api/user/:id),不是当前请求的真实路径。
典型场景:静态资源 /public/* 和健康检查 /health 绝对不能被 IP 拦截;而 /api/v1/users 必须严格校验。
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 白名单逻辑要放在中间件开头,匹配成功后直接
return c.Next(),让请求继续往下走 - 白名单 key 必须和黑名单一致(都用
c.IP()或统一的可信字段),否则出现“同个 IP 既被拦又被放” - 不要在白名单分支里写
c.SendString()后不return,那会导致响应体写出两次(Fiber 会 panic)
怎么限制某个路由只接收 JSON 数据
重点不是 Accept 头,而是检查 Content-Type 请求头。用 strings.HasPrefix(c.Get("Content-Type"), "application/json") 判断,不匹配就立刻返回 415,且不调 c.Next()。
c.BodyParser(&v) 不会自动拒绝非 JSON 请求体——如果前端发来 Content-Type: text/plain 却塞了 JSON 字符串,BodyParser 仍会尝试解析,这违背“只接收 JSON”的语义。
- 中间件注册要用
app.Post("/api/user", jsonOnly(), handler),而不是app.Use(jsonOnly())全局应用 - 中间件内部必须自己判断当前路径和方法,避免误拦
GET /health这类纯文本端点 - 函数签名必须是
func(c *fiber.Ctx) error,先用c.Method()和c.Path()粗筛,再检查Content-Type
怎么防止 405 Method Not Allowed 被默认硬编码返回
Fiber 的 405 响应由路由层直接返回,不经过任何中间件链,也无法被 app.SetErrorHandler() 捕获。你无法“拦截”它,只能主动覆盖。
正确做法是显式注册所有可能的方法组合,用 app.All() 或按方法逐个注册,再在 handler 中判断是否允许:
-
app.All("/api/user", methodGuard("GET", "POST", "DELETE"))是常用模式 - 别依赖浏览器
<form method="put"></form>——HTML 规范只支持 GET/POST,method="put" 会被忽略并退化成 GET - 真 PUT/DELETE 必须用 JS 发送:
fetch("/api/user/123", { method: "PUT", body: JSON.stringify(...) }) - 跨域带
Authorization头?浏览器会先发 OPTIONS 预检——没配cors.New(),就卡在预检失败,表现为只有 OPTIONS 请求且状态码是 404/405
Fiber 的路由拦截和防护不是靠“挂一个中间件就万事大吉”,关键点在于:路径判断必须早于业务逻辑、Content-Type 校验必须在 BodyParser 之前、405 必须靠显式注册而非拦截、IP 校验必须用 c.IP() 而非原始 header。这些顺序和时机错一点,防护就形同虚设。


















