应使用 c.fullpath() 获取注册路由模式匹配白名单,预编译正则支持通配符,确保白名单中间件在 jwt 和 cors 中间件之前执行,并单独放行 options 请求。

白名单中间件怎么写才不漏请求
直接用 gin.HandlerFunc 拦截,但别只比对完整 URL —— 路由带参数(如 /user/:id)或带查询参数(?v=1)时,硬匹配会失败。应该提取路径模板后缀做匹配,比如把 /user/123 归一化为 /user/:id 再查白名单。
推荐做法:在中间件里调用 c.FullPath() 获取注册时的路由模式(不是原始路径),再跟白名单列表比对。Gin 的 c.FullPath() 在路由匹配完成后才可用,确保放在其他中间件之后、handler 之前执行。
- 白名单配置用 map[string]struct{},查 O(1),别用 slice 遍历
- HTTP 方法也要校验,
GET /health和POST /health应分开控制 - 开发环境可设开关绕过白名单,但上线前必须关闭,避免漏配导致 403
如何让白名单支持通配符和前缀匹配
纯字符串匹配太死板。/api/v1/user/* 这种写法没法直接用 strings.HasPrefix,因为 Gin 的注册路径是 /api/v1/user/:id,不是文件路径。
实际方案是预编译白名单规则:遇到 * 就转成正则 ^/api/v1/user/.*$;遇到 /** 可展开为多级子路径匹配;普通路径保持字面量精确匹配。注意正则要加锚点,否则 /user 会误中 /users。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 用
regexp.Compile预热所有规则,别在每次请求里Compile,否则性能崩 - 白名单加载时做语法校验,遇到非法正则立刻 panic,别等运行时报错
-
/admin/**和/admin同时存在时,按最长前缀优先,需排序后再编译
白名单和 JWT 权限控制怎么共存
白名单只放免鉴权接口,比如 /login、/health、/swagger/*;其余接口统一走 JWT 中间件。关键在于执行顺序:白名单中间件必须在 JWT 中间件之前注册,否则未登录用户连白名单接口都进不来。
注册顺序示例:r.Use(whitelistMiddleware()) → r.Use(jwtMiddleware()) → r.GET("/login", loginHandler)。如果反过来,/login 会被 JWT 拦住,永远触发不了白名单逻辑。
- JWT 中间件里别重复校验白名单路径,它只管已通过白名单的请求
- 某些接口既要白名单放行、又要角色校验(如管理员专属健康检查),那就得在 handler 里二次判断,白名单不负责权限粒度
- 测试时用 curl 模拟未带 token 的请求,确认
/health返回 200,/user返回 401,而不是全 403
为什么 OPTIONS 预检请求总被白名单拒绝
浏览器发 CORS 预检时,c.FullPath() 是空字符串,c.Request.URL.Path 是原始路径(如 /api/data),但 Gin 默认不把 OPTIONS 注册为独立路由,所以白名单查不到对应项。
解法只有两个:一是显式注册 OPTIONS 路由并加入白名单,二是中间件里单独处理 c.Request.Method == "OPTIONS",直接 c.AbortWithStatus(204) 放行,不走后续匹配逻辑。
- 不要试图在白名单里加
OPTIONS /*这种规则,Gin 不会把预检请求分发到你定义的路由上 - 如果用了
gin-contrib/cors,它的中间件默认处理 OPTIONS,此时你的白名单中间件应放在 cors 之后,否则 cors 的响应头可能被拦截 - 用
curl -X OPTIONS -H "Origin: http://example.com" http://localhost:8080/api/data验证是否返回 204
c.FullPath() 或多一个 c.Next(),就可能让整个鉴权链失效。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










