Beego自定义Filter需定义func(*context.Context)函数并用beego.InsertFilter()在beego.Run()前显式注册,注册顺序决定执行顺序,路径匹配支持通配符如/api/*,终止请求应使用ctx.AbortWithStatusJSON()返回带状态码的JSON响应。

Beego 中如何定义和注册自定义 Filter
Beego 的拦截器叫 Filter,本质是函数类型 func(*context.Context),必须手动注册到 beego.InsertFilter() 才生效。不注册就等于没写。
常见错误是写了函数但漏掉注册,或者注册时机不对(比如放在 main() 之外、或在 beego.Run() 之后)。
- 注册必须在
beego.Run()之前,通常放在main.go的init()或main()开头 - Filter 执行顺序由注册顺序决定,越早注册越早执行(前置过滤器)
- 支持按路径匹配:
/api/*、/admin/:id等,注意通配符语法不是正则 - 路径匹配区分 HTTP 方法:用
beego.BeeApp.Handlers.AddMethodFilter()可限定 GET/POST
怎么在 Filter 中终止请求并返回 JSON 错误
Beego 的 *context.Context 提供了 Abort() 和 AbortWithStatusJSON(),前者只中断流程,后者能同时设状态码+JSON 响应体。
直接调 ctx.Abort(401) 不会自动写响应内容,前端可能收空体;而 ctx.AbortWithStatusJSON(401, map[string]string{"error": "unauthorized"}) 才真正完成“拦截并返回”。
-
Abort()后框架不再执行后续 Filter 和 Controller,但也不会自动输出任何内容 -
AbortWithStatusJSON()内部已调用ctx.ResponseWriter.WriteHeader()和json.Marshal(),无需再手动写 - 如果需要自定义 Content-Type 或加 Header,得在
AbortWithStatusJSON()前手动设置ctx.ResponseWriter.Header().Set()
Filter 里怎么读取和修改请求参数或 Header
Filter 运行时,ctx.Input 已完成基础解析,可直接用 ctx.Input.Param()、ctx.Input.Query()、ctx.Input.Header() 读取;修改需调 ctx.Input.SetData()(仅对 Controller 可见),或直接操作 ctx.Request(慎用,可能破坏中间件链)。
-
ctx.Input.Query("page")读 URL 查询参数,ctx.Input.Post("name")读表单字段 -
ctx.Input.Header("Authorization")获取 Header,注意键名自动转为驼峰格式("X-Request-ID"→"X-Request-Id") - 想把 token 解析结果透传给 Controller,推荐用
ctx.Input.SetData("user_id", 123),Controller 里用this.Input.GetData("user_id")取 - 不要直接改
ctx.Request.URL或ctx.Request.Body,Beego 的路由和参数解析依赖原始值
为什么 Filter 拦不住 OPTIONS 预检请求
Beego 默认跳过对 OPTIONS 请求的 Filter 执行——这是设计行为,不是 bug。框架在 router.go 内部做了短路处理,直接返回 200,不进 Filter 链。
如果你需要统一鉴权或日志记录覆盖预检请求,必须显式启用 CORS 并配置 beego.BeeApp.Handlers.EnableCORS = true,或自己注册一个 OPTIONS 路由兜底:
beego.Router("/api/*", &MyController{}, "options:Options")
然后在 Options() 方法里手动复用你的鉴权逻辑,否则 Filter 对 OPTIONS 完全不可见。











