Permission as view
What the user sees should equal what they can do. Show them things they cannot access and then block them — that is making them hit a wall every time.
- 点了才提示没权限,用户不知道该找谁开
- 前端把按钮藏起来了,但接口没拦,改个请求就能越权
- 加一个新角色要改十几个页面,因为权限是散在各处写死的
Three kinds of permission
First sort out which kind it is — the implementation is completely different.
| 类型 | 控制什么 | 界面上表现为 |
|---|---|---|
| 页面权限 | 能看到系统里的哪些页面 | 导航菜单里有没有这一项。没权限就不出现 |
| 操作权限 | 能在页面上做哪些动作 | 按钮显不显示:查看、新增、修改、删除、审核 |
| 数据权限 | 同一个页面能看到哪些数据 | 列表里的条数不同。销售只看自己的客户 |
Granularity can split one more layer: admin, edit, preview. Admin can assign permissions and delete data; edit can change content; preview can only view. Document products often add independent toggles for download, upload, and public sharing.
How to build RBAC
Do not bind permissions directly to users. Slip a role layer in between and both adding people and adding permissions turn into configuration.
Design it in three steps: list the roles first (by org structure or by system structure), then list the permissions (pages, operations, data — three kinds), and finally draw a role-by-permission matching table. Once that table is drawn, most of the permission design is done.
How to handle it in the UI
- Don't show entries the user has no permission for. They don't appear in the nav; buttons aren't rendered. This is the default.
- Show-but-disable only in one case: the user knows the feature exists and can apply for it themselves. In that case the disabled state needs a line like "contact your admin to enable," otherwise it says nothing.
- The backend has to gate again. Hiding on the frontend is an experience decision, not a security one. Without API checks, a tweaked request crosses the line (see the security basics in understand tech).
- Filter data permission at the query layer. Not "fetch everything and filter on the frontend."
- Permission changes need feedback. The admin just granted you access; you have to refresh to see it — that's a good moment for a hint.
A note for AI
## 权限 模型:RBAC。用户 → 角色 → 权限,不要把权限直接绑在用户上。 权限分三类,每类都要实现: - 页面权限:无权限时导航项不渲染,直接访问 URL 也要拦 - 操作权限:无权限时按钮不渲染,不要渲染后禁用 - 数据权限:在查询条件里过滤,不要查全量再在前端筛 颗粒度:管理 / 编辑 / 预览三档。 强制要求: - 前端的隐藏只是体验优化,每个接口都必须独立校验权限, 不能依赖前端不发请求。 - 新增任何接口时,先说明它需要哪个权限,再写实现。 - 涉及数据权限的查询,把过滤条件写进 SQL 或 ORM 查询, 并在代码注释里说明过滤依据。 例外情况(显示但禁用)只用于:用户知道有这个功能且能自行申请, 此时禁用态必须带一句说明,告诉他找谁开通。
