概述
基于 RBAC 角色权限设计,前后端各自管理权限字典
- 菜单及权限对应UI级别的按钮显示与隐藏由前端控制
- 后端以权限码映射到具体的接口权限
- 权限码列表在登录接口中根据当前用户的角色,仅返回当前用户对应角色所具有的权限(即用户所在角色不具备的权限不在接口返回)
- 用户权限发生变更时处理方案
- 直接将用户当前的登录 token 过期,用户需要重新登录
- 通过 websocket 等手段下发变更权限
- 目前简单处理选用方案 1
- 后端返回 http 状态码 401 的情况:token 过期、token 格式错误
- 后端返回 http 状态码 403 的情况:用户角色权限不足
权限码定义
权限码按后端接口逻辑定义,示例:Report.R
CURD
- C = Create
- U = Update
- R = Retrieve
- D = Delete
自定义
- I = Import
- E = Export
- S = Sync
接口示例
登录接口
{
"roleId": "60d437f7d548b939f9ab70d7",
"roleName": "管理员",
// 返回用户当前所在角色中所拥有的权限id列表
"pmIds": ["60d437f7d548b939f9ab70d7", "60d437f7d548b939f9ab70d1", "60d437f7d548b939f9ab70d3", "60d437f7d548b939f9ab70d5"]
}
特殊处理
系统预置角色
- 系统预置角色包含:管理员、普通员工等
- 对于预置角色:无法删改其内容,无法修改其权限
- 如果用户当前角色为自定义角色,该角色被删除后,用户角色默认变更为【普通员工】预置角色
数据权限
上述权限方案仅限于处理前端按钮及后端接口访问粒度,对于某些场景下,需要对用户的可访问数据范围做限制时,应在角色外再定义一层用户数据权限。
比如,用户具有项目列表接口访问权限,但在数据上进允许用户访问某些地区的项目,那应该基于功能权限外,再给用户定义可访问的数据范围,并在逻辑实现处做拦截处理。
在微服务场景下的适配
上述权限方案对应的每个接口需要处理接口与权限码的映射关系,在标准的 SpringBoot 项目架构下,可以使用权限码注解等方式实现。在微服务场景下,可使用的映射方案为:
- 在网关层配置接口 - 权限码映射关系,接口可由地址+请求方法唯一确定
请求到达网关时即可根据地址+请求方式,判断用户是否具备该接口访问权限
- 设计BFF层,将该层当做标准单体架构,权限拦截在BFF层完成
可以根据不同的BFF层灵活设计拦截方案,包括白名单放通等