beforestatic 是唯一能拦截静态文件请求的过滤器,因为 beego 对静态资源采用短路逻辑,直接跳过路由匹配和控制器流程,导致 beforerouter 等全部失效。

静态文件请求不会触发 BeforeRouter 或 BeforeExec 过滤器,想对 /static/users/{id}/private/ 这类路径做权限控制,必须用 BeforeStatic。
为什么 BeforeRouter 对静态文件完全无效
Beego 的静态资源处理是短路逻辑:一旦请求 URL 匹配到任一已注册的静态目录(如 beego.SetStaticPath("/static", "static")),框架就跳过整个路由匹配和控制器执行流程,直接交由内置静态处理器响应。此时 BeforeRouter、BeforeExec、AfterExec 全部不执行。
常见错误现象:
- 在
BeforeRouter里写日志或校验逻辑,但访问/static/js/app.js时日志没输出、校验没生效 - 用正则路由
/:path.*拦截所有路径,仍无法捕获静态请求 - 误以为加了
beego.InsertFilter("/*", beego.BeforeRouter, authFilter)就能统一鉴权
BeforeStatic 是唯一可靠的拦截点
该过滤点在静态文件处理器读取磁盘前调用,且只对命中静态路径的请求触发。它接收完整 *context.Context,可读取 ctx.Input.URL()、ctx.Input.IP()、ctx.Input.Session 等,适合做路径解析、用户身份校验、白名单判断。
实操建议:
- 注册位置必须在
beego.Run()之前,且早于任何SetStaticPath调用(顺序无关紧要,但习惯上放一起) - 过滤器内需手动解析路径,例如用
strings.Split(ctx.Request.URL.Path, "/")提取id,再查 DB 或 Session 判断当前用户是否有权访问该用户私有目录 - 若校验失败,直接调用
ctx.Abort(403)或ctx.Redirect(302, "/login"),不要调用ctx.Next() - 注意:该过滤器对所有静态请求生效,若只保护部分路径,开头需加路径前缀判断,如
if strings.HasPrefix(ctx.Request.URL.Path, "/static/users/")
配置多个静态路径时的过滤器作用范围
BeforeStatic 过滤器对所有注册的静态路径统一生效,不区分 SetStaticPath("/static", "static") 还是 SetStaticPath("/down1", "download1")。这意味着你可以在一个过滤器里集中处理不同静态域的权限逻辑。
性能与兼容性影响:
- 每次静态请求都会进入该过滤器,避免在其中做耗时操作(如远程 HTTP 请求、复杂 SQL 查询)
- 推荐使用内存缓存(如
sync.Map)缓存近期校验结果,或提前将权限信息注入 Session - Beego v2.x 全版本均支持
BeforeStatic,无兼容性风险;v1.x 不支持该过滤点,需升级
最容易被忽略的是:静态请求绕过了整个 MVC 生命周期,连 Controller 的 Prepare() 方法都不会执行。别指望用控制器层逻辑兜底——BeforeStatic 是唯一的入口,也是最后一道防线。











