中后台 RBAC:前端可见性不是安全边界
一个可维护的权限系统要让角色、资源和动作有稳定语义。前端负责菜单、路由、页面区块和按钮的可见/可用体验;后端负责每个数据与写操作的最终授权。
权限模型
text
用户 ──拥有──> 角色 ──授予──> 权限码
├─ page:activity:list
├─ activity:create
├─ activity:publish
└─ activity:rollback权限码使用业务语义,不与组件名或 DOM 绑定。菜单可以由授权路由推导,也可以由后端返回菜单模型,但最终都要映射到同一套权限码。
前端执行链路
- 登录或恢复会话。
- 拉取用户、角色与权限码。
- 生成/过滤动态路由和菜单。
- 路由守卫拦截未授权导航。
- 页面用统一指令/组件控制操作入口。
- 接口返回 401/403 时分别处理登录失效与权限不足。
vue
<PermissionGate permission="activity:publish">
<button type="button" @click="publish">发布</button>
</PermissionGate>组件方式比只操作 DOM 的指令更适合表达禁用原因、占位和无障碍文本;指令适合简单按钮隐藏。无论哪种,接口都必须二次鉴权。
缓存与角色切换
权限缓存要带用户/租户/版本维度。登出或切换角色时清除旧 Store、移除动态路由、终止进行中的请求,再重新拉取权限。否则旧页面、旧按钮甚至旧数据都可能残留。
测试清单
- 未登录、会话过期、权限接口失败。
- 有页面权限但无发布权限。
- 角色切换后旧路由被移除。
- 直接输入未授权 URL。
- 前端展示错误但后端正确拒绝越权请求。
- 批量操作中部分记录无权限时的结果明细。
更完整的路由实现见 Vue Router 与 RBAC。