Cursor 能生成 CRUD,为什么 Go 后台权限还是会漏:RBAC 菜单和接口要一起验
Cursor 能把一个后台 CRUD 很快写出来但权限经常不是“顺手就对”的东西。页面能打开、列表能查、新增能保存只能说明业务链路通了不能说明角色、菜单、按钮和接口已经绑定到同一套规则里。我更愿意把 AI 生成的后台代码当成半成品。它能省掉重复文件但权限边界必须单独验。最常见的误判是前端菜单隐藏了开发者就以为这个角色没有权限实际接口还在只要知道 URL照样能打到后端。这篇只看一个问题AI 或代码生成器生成 Go 后台 CRUD 后怎么检查 RBAC 权限有没有漏到接口层。示例用 GoFrame 写法SQL 和 curl 可以直接换到自己的项目里跑。先准备一个最小 RBAC 结构后台权限至少要分清四类东西用户、角色、菜单、接口动作。很多项目只做到前三个问题就出在第四个。CREATE TABLE admin_user_role ( user_id BIGINT NOT NULL, role_id BIGINT NOT NULL, PRIMARY KEY (user_id, role_id) ); CREATE TABLE admin_role_menu ( role_id BIGINT NOT NULL, menu_id BIGINT NOT NULL, PRIMARY KEY (role_id, menu_id) ); CREATE TABLE admin_menu ( id BIGINT PRIMARY KEY, parent_id BIGINT DEFAULT 0, title VARCHAR(64) NOT NULL, name VARCHAR(64) NOT NULL, path VARCHAR(128) DEFAULT , api_perm VARCHAR(160) DEFAULT , type VARCHAR(16) NOT NULL );type可以分成menu和button。菜单负责路由显示按钮负责具体动作。关键字段是api_perm比如GET /admin/user/list POST /admin/user/save DELETE /admin/user/delete如果你的后台只靠前端路由控制那就少了这层映射。AI 生成 CRUD 时也容易漏掉它因为提示词通常会说“生成增删改查页面和接口”很少明确说“把每个接口挂到角色菜单权限表上”。一个很容易漏的场景假设运营角色只能看用户列表不能新增、不能删除。前端会把新增按钮隐藏掉页面看起来没问题。但如果后端没有检查接口权限下面这个请求仍然可能成功curl -i http://127.0.0.1:8000/admin/user/save \ -H Authorization: Bearer 运营角色token \ -H Content-Type: application/json \ --data {username:test01,nickname:测试用户}你希望看到的是 403HTTP/1.1 403 Forbidden {code:403,message:无操作权限}如果返回 200就不是前端按钮的问题了。这个角色已经绕过页面限制直接调用了接口。GoFrame 中间件应该检查什么后端不要只判断“登录了没有”。登录校验解决身份问题权限校验解决这个身份能不能做当前动作。下面是一个简化版中间件只保留核心逻辑func AdminPermission(r *ghttp.Request) { user : contexts.GetUser(r.Context()) if user nil { r.Middleware.Next() return } if consts.IsSuperRole(user.RoleKey) { r.Middleware.Next() return } perm : strings.ToUpper(r.Method) r.URL.Path menuIds : findMenuIdsByPerm(r.Context(), perm) if len(menuIds) 0 { r.Middleware.Next() return } ok, err : userHasMenuPermission(r.Context(), user.Id, menuIds) if err ! nil { g.Log().Warningf(r.Context(), 权限校验异常: %v, err) r.Response.WriteStatusExit(500) return } if !ok { r.Response.WriteStatusExit(403) return } r.Middleware.Next() }这里有两个点不能省。第一权限 key 用METHOD path不要只用 path。GET /admin/user和POST /admin/user往往不是同一个权限。第二没有找到权限配置时怎么处理要按项目阶段定。内部后台早期可以放行方便迁移正式上线后更推荐记录日志并逐步收紧否则新接口很容易裸奔。用 SQL 反查角色到底有没有接口权限调权限问题时不要只看页面。直接查表更快。比如用户1001调POST /admin/user/save可以这样查SELECT arm.role_id, arm.menu_id, am.title, am.name, am.api_perm FROM admin_user_role aur JOIN admin_role_menu arm ON arm.role_id aur.role_id JOIN admin_menu am ON am.id arm.menu_id WHERE aur.user_id 1001 AND am.api_perm POST /admin/user/save;有记录说明角色拿到了这个接口动作没有记录就应该拦。再查一下接口本身有没有挂菜单SELECT id, title, name, type, api_perm FROM admin_menu WHERE api_perm POST /admin/user/save;如果这条也查不到说明接口没有进入权限体系。AI 生成了 controller、service、dao但没有补权限元数据这就是典型缺口。新增和编辑共用接口时要特别小心很多后台会把新增和编辑合到一个save接口有id就编辑没有id就新增。页面上是两个按钮后端却是同一个 URL。此时只用POST /admin/user/save映射一个权限会出现“有编辑权限就顺便能新增”的问题。一种做法是在中间件里根据参数区分func resolveAction(r *ghttp.Request, items []permItem) []uint64 { if len(items) 1 { return []uint64{items[0].MenuId} } id : r.Get(id) target : add if id ! nil !id.IsEmpty() id.Int64() 0 { target edit } for _, it : range items { if strings.Contains(strings.ToLower(it.Name), target) { return []uint64{it.MenuId} } } return nil }这个判断看着小但很实用。AI 生成 CRUD 时通常不会主动想到“同一个 save 接口背后对应两个按钮权限”所以这类代码要人工补上或者让代码生成器在模板层就固定生成。发布前至少跑 4 个验证我一般不相信“页面点过没问题”。后台权限要用反向验证。验证项怎么验期望结果未登录访问接口不带 token 调接口401无菜单权限访问页面用低权限角色登录菜单不可见无按钮权限访问接口直接 curl 新增/删除接口403有权限角色访问接口用管理员或授权角色调用200对应的 curl 可以写进项目脚本里TOKEN低权限角色token BASEhttp://127.0.0.1:8000 curl -s -o /tmp/save.out -w %{http_code}\n \ $BASE/admin/user/save \ -H Authorization: Bearer $TOKEN \ -H Content-Type: application/json \ --data {username:no_perm_user} cat /tmp/save.out如果状态码不是 403就继续查admin_menu.api_perm和admin_role_menu。不要先怀疑前端。AI 和代码生成器各自适合做什么AI 适合补样板代码尤其是字段多、接口重复、前后端文件都要改的时候。但权限这种东西有上下文哪个角色能做什么按钮和接口是不是一一对应新增和编辑是否共用 URL接口缺配置时默认放行还是拒绝。这些不是“生成 CRUD”四个字能推出来的。更稳的做法是让生成器负责固定结构让 AI 负责局部修改和解释让测试脚本负责兜底。比如在 XYGo Admin 的真实代码里server/internal/middleware/admin_permission.go已经把METHOD path、角色菜单表和新增/编辑分流放在后端检查server/internal/dao/admin_role_menu.go、server/internal/model/entity/admin_role_menu.go对应角色与菜单关系。需要看源码可以从这里进https://github.com/z312193608/xygo-admin这不是说 AI 不能写后台。恰好相反AI 写后台会越来越常见。只是权限不能停在“页面看起来对”。后台管理系统真正要验的是看不到按钮的人直接打接口也不能成功没有角色关系的人查表也找不到对应菜单动作新增和编辑共用接口时权限仍然能分开。如果只验 CRUD 是否能跑AI 生成的代码会显得很顺。如果把 RBAC、SQL、curl 和日志一起验才知道这个后台能不能给真实用户用。

相关新闻