Beego中间件无法直接注入依赖,须通过全局变量(如GlobalApp)或beego.AppConfig传递;Filter函数签名固定为func(*context.Context),注册须在beego.Run()前且阶段匹配(如静态资源用BeforeStatic),并确保Wire初始化完成后再注册Filter。

Beego中间件里不能直接注入依赖,得靠全局变量或上下文传递
Beego 的中间件(即 Filter 函数)签名固定为 func(*context.Context),没有构造函数、不参与 DI 生命周期,因此 Wire 生成的依赖实例无法自动塞进去。你写 func AuthFilter(ctx *context.Context, svc *UserService) 会编译报错——Go 不支持函数参数注入。
常见错误是试图在 Filter 里调用 beego.AppConfig.Get() 或直接 new 一个 service,结果发现配置未加载、DB 连接为空、或者并发下 panic。
- 正确做法:把初始化好的依赖(如
*UserService、*cache.Cache)挂到包级变量或beego.AppConfig的自定义字段上,在 Filter 中直接读取 - 更可控的方式:定义一个
type App struct { UserService *UserService; Cache *cache.Cache },在main()中通过wire.Build()初始化后赋值给全局var GlobalApp *App,Filter 中统一用GlobalApp.UserService.CheckToken() - 千万别在 Filter 里做
orm.NewOrm()或sql.Open()—— 每次请求都新建连接,很快打爆数据库
Filter 注册必须在 beego.Run() 前,且阶段选错就拦截不到请求
中间件注册晚了等于没写;阶段选错会导致关键路径(比如 /static/)完全绕过校验。比如把权限检查放 beego.BeforeRouter,静态资源请求根本不会触发它,因为 Beego 对 /static/ 是直通文件系统,不走路由匹配。
- 静态资源权限控制唯一有效阶段是
beego.BeforeStatic,但注意:此时ctx.Input.Param()和ctx.Controller都未初始化,要用strings.Split(ctx.Request.URL.Path, "/")或正则手动提取路径段 - 需要读取 POST body 或解析表单?只能放在
beego.BeforeExec,这时ctx.Input.RequestBody和ctx.Input.Data才可用 - 注册顺序影响执行链:
beego.InsertFilter("/admin/*", beego.BeforeExec, LogFilter)必须在beego.InsertFilter("/admin/*", beego.BeforeExec, AuthFilter)之前,否则日志里看不到认证失败详情
Filter 中调用 ctx.Next() 和 ctx.Abort() 的坑比想象中多
很多开发者以为 return 就能终止请求,结果后续 Filter 和 Controller 还是被执行了——因为 Beego 的过滤器链是显式控制流,不是 Go 的 defer 或回调。
-
ctx.Abort(401, "Unauthorized")是标准终止方式,它会清空响应体、设置状态码,并跳过后续所有 Filter 和 Controller - 漏掉
ctx.Next()导致整个链路中断,Controller 永远不会运行;写成defer ctx.Next()更危险,它是异步延迟执行,和预期的“继续往下走”逻辑完全相反 - 在
BeforeStatic阶段调用ctx.Abort()后,别再碰ctx.ResponseWriter—— Beego 已接管响应,重复写入会 panic
Wire 初始化和 Filter 之间的时序必须手动对齐
Wire 生成的 InitApp() 返回 *App,但它只是个结构体,不自动绑定到 Beego 运行时。如果 Filter 在 InitApp() 之前执行,读到的 GlobalApp 就是 nil。
- 确保
GlobalApp = InitApp()在beego.InsertFilter()调用之前完成,典型顺序是:initDB()→GlobalApp = InitApp()→beego.InsertFilter(...)→beego.Run() - 不要把
InitApp()放进init()函数——它依赖配置加载(如beego.AppConfig.String("db::url")),而init()执行早于beego.LoadAppConfig(),大概率拿到空字符串 - 测试时容易忽略这点:单元测试中若只 mock 了 Controller,没初始化
GlobalApp,Filter 一跑就 panic
BeforeStatic 阶段的参数提取方式和 GlobalApp 的初始化时机——这两处出问题,线上可能连续几小时静默放行非法静态资源访问,日志里还找不到痕迹。


















