Fiber 中间件需手动判断路径前缀(如 c.Path())和 IP(c.IP()),并显式 return 中断链;代理场景下必须配置 ProxyHeader 和 TrustedProxies 才能获取真实客户端 IP。

直接用 app.Use() 挂中间件 + c.Path() 判断路径前缀,再结合 c.IP() 查黑白名单 map,不是靠路由注册本身做拦截——Fiber 的路由树不提供“某条路由只允许某些 IP 访问”的声明式配置。
怎么让中间件只对特定路径生效(比如只拦 /api/*)
必须手动判断 c.Path(),Fiber 没有路径级开关:
-
app.Use("/api", ipFilterMiddleware)是最简方式:它匹配所有以/api开头的路径(/api、/api/users、/api/v2/payments),且对所有 HTTP 方法生效 - 别用
app.Get("/api/*", ...)替代——它注册的是一个 handler,不是中间件,无法提前拦截;而且*通配会覆盖后续更具体的路由(如/api/users/:id可能根本收不到请求) - 若需更细粒度(如只拦
/api/admin但放行/api/public),在中间件里写:if strings.HasPrefix(c.Path(), "/api/admin") { /* 拦截逻辑 */ } - 注意
c.Path()不含 query string,比c.OriginalURL()更干净;也别用strings.Contains(c.Path(), "admin"),可能误伤/api/users?search=admin
为什么 c.IP() 返回的总是 127.0.0.1 或内网地址
因为没配置可信代理头,c.IP() 默认只信任回环地址:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 前置了 Nginx/Traefik/CDN 时,必须显式设置
app.Config().ProxyHeader = "X-Real-IP"(前提是 Nginx 已配proxy_set_header X-Real-IP $remote_addr) - 若走多层代理(如 CDN → Nginx → Fiber),应设
app.Config().ProxyHeader = "X-Forwarded-For",并确保X-Forwarded-For头未被客户端伪造——可通过app.Config().TrustedProxies加入可信网段(如[]string{"192.168.0.0/16", "203.208.60.0/24"}) - 测试时 curl 本地发请求,
c.IP()就是127.0.0.1,不是 bug,是预期行为;真要测公网 IP 效果,得从外网机器或用代理链 - 别直接读
c.Get("X-Forwarded-For")后取第一个 IP——它可被伪造;必须配合TrustedProxies校验来源是否可信,再取链尾真实 IP
黑名单命中后请求还在往下走?漏了 return
Fiber 不自动中断中间件链,忘写 return 就等于放行:
- 黑名单逻辑必须带
return c.Status(403).SendString("Forbidden"),不能只写c.Status(403).SendString(...)然后继续执行 - 白名单逻辑要放在中间件开头,匹配成功后
return c.Next(),否则默认执行后续校验(如 JWT 验证、限流) - 数据结构别用切片遍历查 IP——性能差且并发不安全;用
map[string]struct{}存黑名单,或sync.Map(若需运行时增删) - 需要 CIDR 支持(如
192.168.1.0/24)?用标准库:_, ipNet, _ := net.ParseCIDR("192.168.1.0/24"); if ipNet.Contains(net.ParseIP(c.IP())) { ... }
真正难的不是写逻辑,是保证 c.IP() 拿到的是真实客户端 IP——一旦代理链配置错,黑白名单就形同虚设;而中间件里少一个 return,整个安全策略就失效。这两处没验证清楚,代码写得再漂亮也没用。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










