Beego过滤器通过beego.InsertFilter()注册,三个参数分别控制路径匹配(pattern)、执行阶段(pos)和处理函数(filter);/static/请求需用BeforeStatic单独注册,所有注册必须在beego.Run()前完成。

Beego 中间件不叫中间件,叫过滤器(Filter),执行顺序由注册位置和路径匹配共同决定,不是按代码书写顺序或函数名排序。
beego.InsertFilter() 的三个参数分别控制什么
调用 beego.InsertFilter() 时传入的三个参数,每个都直接影响执行时机:
-
pattern:路径前缀匹配字符串,如"/api/"、"/*"或"/static/private/";空字符串""不匹配任何请求 -
pos:执行阶段,必须是beego.BeforeRouter、beego.BeforeStatic等固定常量;不同阶段完全隔离,BeforeRouter里的过滤器永远看不到/static/请求 -
filter:函数值,签名必须是func(*context.Context);不能返回值,不能用defer ctx.Next(),必须显式调用ctx.Next()才能继续链路
为什么 /static/ 路径的请求总绕过你的权限检查
因为 Beego 把静态资源处理从主路由流程中完全剥离了——它不走 BeforeRouter,也不进 BeforeExec,只在 BeforeStatic 阶段开放一个钩子。
- 如果你把鉴权逻辑注册在
beego.BeforeRouter,那对/static/xxx请求根本不会触发 - 必须单独注册一次:
beego.InsertFilter("/static/private/", beego.BeforeStatic, staticAuthFilter) -
BeforeStatic阶段的ctx对象里,ctx.Input.Param()、ctx.Controller、c.Data全为 nil,参数得自己从ctx.Request.URL.Path里用正则或strings.Split()扒 - 如果同时要限制
/api/和/static/private/,就得写两套逻辑、注册两次,没法复用
多个过滤器注册后到底谁先执行
同一 pos 阶段、相同 pattern 下,过滤器按 InsertFilter() 的调用顺序执行;但跨 pattern 或跨 pos 就不构成“先后”关系——它们根本不在同一条链上。
- 注册顺序示例:
beego.InsertFilter("/api/", beego.BeforeRouter, A)→beego.InsertFilter("/*", beego.BeforeRouter, B)→beego.InsertFilter("/api/v2/", beego.BeforeRouter, C) - 访问
/api/user时,只触发 A 和 B,顺序是 A → B(因为 A 的 pattern 更精确,但 Beego 不做优先级排序,只按注册顺序) - 访问
/api/v2/list时,A、B、C 全部触发,顺序是 A → C → B(C 在 A 之后、B 之前注册) - 别依赖 pattern 长度或字典序,只依赖你调用
InsertFilter()的实际顺序
最容易被忽略的是:所有 InsertFilter() 必须在 beego.Run() 之前完成,哪怕只晚一行,整个过滤器就静默失效——没有报错,没有日志,请求就像没经过它一样。


















