Beego中间件未触发,主因是beego.InsertFilter()注册过晚或阶段错误:必须在beego.Run()前注册,静态资源需用beego.BeforeStatic阶段,/api/路径拦截应写为"/api/"(带尾斜杠),多中间件按注册顺序执行但阶段间互不干扰。

中间件没触发?先确认注册时机和阶段
Beego 中间件不执行,90% 是因为 beego.InsertFilter() 调用太晚或阶段选错。它必须在 beego.Run() 之前注册,且不能放在 controller 或路由 init 里——那些时机早已错过请求链启动点。
常见错误现象:/api/users 请求完全没进中间件、/static/logo.png 权限校验失效、日志行根本没输出。
- 静态资源(
/static/)必须用beego.BeforeStatic阶段注册,BeforeRouter和BeforeExec对它完全无效 - 想只拦截
/api/开头的请求,注册路径写成"/api/"(带结尾斜杠),别用"/api",否则会误匹配/apixxx - 多个中间件按注册顺序执行,但不同阶段(如
BeforeStatic和BeforeExec)互不干扰,不是同一链条
中间件里打日志却看不到输出?检查 ctx.Next() 和 abort 逻辑
Beego 中间件不是“函数调用完就结束”,ctx.Next() 是显式控制流跳转点。漏掉它,后续所有逻辑(包括 controller)都会被跳过;多写一次或包在 defer 里,会导致重复执行或 panic。
常见错误现象:请求卡住、返回空白页、日志只打印前半段、ctx.Input.Param() 在 BeforeStatic 阶段 panic。
-
ctx.Abort(401, "Unauthorized")后必须return,否则ctx.Next()还会继续执行 -
BeforeStatic阶段没有解析过的路由参数,ctx.Input.Param(":id")必然为空,得自己从ctx.Request.URL.Path里截取 - 想测中间件是否运行,最简单方式是在函数开头加
log.Println("hit auth filter:", ctx.Request.URL.Path),别依赖 controller 日志反推
POST 请求体读取失败?注意方法判断和 body 解析时机
Beego 不自动解析 POST body,除非你手动调 ctx.ParseForm() 或 ctx.Input.RequestBody。但在中间件里盲目调用,会导致 GET 请求阻塞——因为 GET 没 body,ReadAll 会等超时。
常见错误现象:GET 请求变慢、ctx.Input.RequestBody 返回空、ParseForm() 报 invalid memory address。
- 只在需要处理 body 的方法中解析:
if ctx.Request.Method == "POST" || ctx.Request.Method == "PUT" || ctx.Request.Method == "PATCH" { ctx.ParseForm() } - 不要在
BeforeRouter阶段尝试访问ctx.Input.Param()或ctx.Input.Query(),这些字段尚未初始化 - 若需统一校验 token,建议从
Authorizationheader 或 cookie 读,不依赖 form 或 json body
调试复杂中间件链?用 ctx.Input.SetData() 传递上下文
多个中间件协作时(比如鉴权 + 日志 + 限流),靠全局变量或闭包传参容易出竞态或生命周期问题。Beego 提供了轻量级上下文存储:ctx.Input.SetData() 和 ctx.Input.GetData()。
常见错误现象:上一个中间件设置的用户 ID,在下一个中间件里取不到、并发请求数据串了、GetData() 返回 nil 但没报错。
-
SetData()存的是 interface{},取出来要类型断言:uid, ok := ctx.Input.GetData("user_id").(int64) - key 名建议加前缀避免冲突,比如
"auth_user_id"而不是直接用"user_id" - 这个机制只在单次请求生命周期内有效,跨请求不共享,不用清理
BeforeExec),问题会表现得像“随机失效”。


















