Beego权限分级需通过InsertFilter按请求阶段(BeforeRouter/BeforeStatic/BeforeExec)和路径前缀显式注册过滤器,统一转换为resource:action格式查用户维度缓存,避免静态资源误匹配、参数未初始化及缓存key无用户隔离三大坑。

Beego 没有“中间件”概念,只有 Filter(过滤器),权限分级必须靠 beego.InsertFilter() 注册多个阶段、多路径、多逻辑的过滤器组合实现,不能只写一个函数塞进去就完事。
权限分级得按请求阶段拆开注册
同一个权限需求,在不同路径类型下触发时机完全不同,强行统一处理必然漏掉请求:
-
/api/类接口走beego.BeforeRouter:此时路由未匹配,但路径和方法已知,适合做通用资源+动作映射(如GET /api/users → user:read) -
/static/类静态文件必须用beego.BeforeStatic:绕过整个路由系统,BeforeRouter完全不触发 - 需要读取
:id等路由参数的校验,只能放beego.BeforeExec:这时ctx.Input.Param(":id")才可用,但静态资源仍不走这里
路径前缀注册比 if 判断更可靠
别在 Filter 函数里写 if strings.HasPrefix(ctx.Request.URL.Path, "/api/v1/admin") —— 这样做容易漏掉 /api/v1/admin/ 末尾斜杠变体,也干扰 Filter 链语义。正确方式是注册时绑定前缀:
beego.InsertFilter("/api/v1/admin/", beego.BeforeRouter, adminOnlyFilter)beego.InsertFilter("/api/v1/user/", beego.BeforeRouter, userOrAdminFilter)beego.InsertFilter("/static/private/", beego.BeforeStatic, staticAuthFilter)
注意所有前缀结尾带 /,否则 /api/v1/admins 会被误匹配。
权限判断逻辑必须标准化 resource:action 格式
直接比对完整路径耦合太重,应统一转成两级标识符再查缓存或 DB:
- 提取
ctx.Request.Method并转大写(GET不等于get) - 清洗路径:去掉版本前缀(如
/v1/)、标准化末尾斜杠(/users/→/users) - 映射规则示例:
POST /api/v1/orders→order:create,GET /api/v1/users/123→user:read - 查权限时用
perm:uid_456内存缓存,key 基于用户 ID,TTL 设 5 分钟,避免每次查库
最容易被忽略的三个坑
权限分级失败,八成卡在这三处:
-
beego.BeforeStatic里调ctx.Input.Param()或ctx.Controller:这些字段根本没初始化,直接 panic - 在
BeforeRouter阶段尝试读ctx.Input.RequestBody:body 尚未解析,值为空,且多次读会失败 - 权限缓存 key 没带用户维度,比如只用
"perm"全局共享:所有用户共用一套权限,一改全乱
分级不是加 if-else 层数,而是把「谁在什么阶段、对什么路径、按什么格式校验」这三件事彻底解耦并显式注册。











