Beego v2中间件必须通过beego.AddMiddleware在beego.Run()前注册,函数需返回func(http.Handler) http.Handler类型,且go.mod须依赖github.com/beego/beego/v2。

Beego 中间件本身不需单独“部署”,它是在应用启动时注册进请求生命周期的 Go 函数,关键在于 app.conf 配置、main.go 初始化顺序、以及中间件代码是否被正确加载。很多报错(如中间件不生效、panic: middleware not found、路由 404 后中间件也不触发)其实都源于环境或初始化逻辑错误,而非中间件写法本身。
beego v2 中间件注册必须在 beego.AddMiddleware 之前调用 Run
Beego v2(github.com/beego/beego/v2)改变了中间件注册机制:不能再像 v1 那样在 init() 或控制器里随意调用 beego.InsertFilter,必须显式通过 beego.AddMiddleware 注册,并且该调用必须发生在 beego.Run() 之前 —— 否则中间件根本不会被挂载。
-
beego.AddMiddleware("beforeRouter", beego.BeeApp.MidWareFunc(myAuthMiddleware))是标准写法,其中"beforeRouter"是执行时机钩子名 - 常见错误:把
AddMiddleware放在beego.Run()之后,或放在某个 controller 的Init()方法里 —— 此时 Beego 已启动 HTTP server,注册无效 - 推荐位置:统一放在
main.go的main()函数开头,在beego.Run()调用前几行
中间件函数签名必须匹配 beego.MiddlewareFunc 类型
Beego v2 对中间件函数签名有严格要求,不是任意函数都能用。传给 beego.BeeApp.MidWareFunc() 的函数必须返回 func(http.Handler) http.Handler,否则运行时报 cannot use ... as func(http.Handler) http.Handler。
- 正确示例:
func myAuthMiddleware() func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("X-Auth-Token") if token == "" { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } next.ServeHTTP(w, r) }) } } - 错误写法:直接写
func(w http.ResponseWriter, r *http.Request)—— 这是 handler,不是 middleware - 注意:不要试图在中间件里调用
beego.Controller.Run()或访问this.Ctx,v2 的中间件处于原生 net/http 层,尚未进入 Beego Controller 生命周期
go.mod 依赖路径必须指向 beego/v2,否则中间件注册不识别
如果项目仍使用旧版 github.com/astaxie/beego(v1),AddMiddleware 和 MidWareFunc 根本不存在,编译直接失败或静默忽略。v1 只支持 InsertFilter,但该方式在 v2 中已被废弃且行为不兼容。
- 检查
go.mod:第一行必须是module your-project-name,且依赖项应为github.com/beego/beego/v2 v2.3.4(以实际最新版为准) - 若误用了 v1,执行
go get -u github.com/beego/beego/v2并手动修改go.mod,再运行go mod tidy - 常见混淆点:bee 工具默认创建的项目仍可能拉取 v1,务必在
bee new后立即检查并修正依赖
中间件不生效?先确认 app.conf 中 enableDocs 和 runmode 是否冲突
Beego 的中间件执行受 app.conf 中两个配置影响:一是 EnableDocs = true 会绕过部分中间件(尤其是 beforeStatic 时机),二是 RunMode = "dev" 下某些调试中间件(如 pprof)可能抢占链路,导致自定义中间件未被执行。
- 排查步骤:临时将
RunMode = "prod",关闭EnableDocs = false,再测试中间件是否触发 - 日志验证:在中间件函数入口加
log.Println("myAuthMiddleware triggered"),看控制台是否输出 - 特别注意:
beforeStatic时机只对静态文件路径(/static/)生效;beforeRouter才覆盖所有路由,包括 API 接口
最易被忽略的是中间件注册顺序和执行时机钩子名的对应关系 —— beforeRouter、afterStatic、finishRouter 等名字必须拼写完全一致,大小写敏感,且不能自定义新名称。一旦写成 before_router 或 BeforeRouter,Beego 就不会调用它,也不会报错,只会静默跳过。











