权限设计

Posted by Solejay on Wed, Jan 25, 2023

权限设计

为什么要有权限设计?

对于一个系统,有多个模块,在需要给不同的用户分配不同的模块权限的场景下,就需要进行权限设计,按需给用户划分对应的权限。比如一个企业系统有用户管理模块、财务管理模块、库存管理模块……对于财务人员来说,只需要财务管理模块的相应权限,不应该分配其他模块的权限;而对于库存人员来说,只需要库存管理模块的权限;对于负责人来说,可能需要所有的模块权限。

权限设计的思路

最开始,用户比较少,就可以用最直观的方式,一个用户需要什么功能,就给他分配功能的权限。

但是随着企业人数逐渐变多,需要分配权限的用户越来越多,刚开始 10 个用户的时候可以手动分配,但是 1000 个用户再手动分配就会变得繁琐低效。

通过对功能分配的观察,有很多用户会分配相同或相似的权限,比如对负责人来说,所有的功能权限都要勾选,每次全都勾选十分复杂,因此可以把这些功能打包起来,成为一个“功能集”。因此可以定义一个“角色”拥有一组功能,就将用户和功能完成了解耦,只需要给用户分配一个角色,便拥有了这个角色对应的所有功能。

如何进行权限设计?

权限设计分为功能权限和数据权限

  • 功能权限:用户登录系统后能看到什么模块,能看到哪些页面

  • 数据权限:用户在某个模块里能看到哪些数据

下面以实际项目为例,介绍项目中如何进行权限设计。

背景信息

项目背景为建设文旅产品,以较为有名的“一机游云南”为例,我们要建设一个“一机游云南”的产品,这个产品包含后台管理系统和小程序,可以在后台编辑活动、咨询、公告等模块,具体的模块下既可以编辑云南省的相关信息,也可以编辑下属景区的信息。如可以编辑云南省的公告信息,也可以编辑下属丽江景区的公告信息。

由于模块众多,且景区众多,让一个管理员来管理工作量显然巨大,因此可以给不同景区和不同模块各自分配相应的管理员来管理。比如可以分配一个管理员拥有丽江、大理的公告模块和活动模块,也可以分配另一个管理员拥有玉龙雪山的咨询、景区信息模块。如果一个管理员没有被分配任何一个景区的公告模块权限,那他就无法看到公告模块,如果只分配了丽江的公告模块权限,那么在公告模块下也只能看到和编辑丽江的信息。

权限系统示意图

采用 RBAC 的思想,用户->角色→权限相分离,用户可以配置多个角色,权限为所有角色的合集

页面设计

由于页面设计相对固定,没有频繁变更功能模块的需求,因此通过配置文件的方式实现。

 1module:
 2  # 有二级页面
 3  - tag: "page_management" # module tag 必须全局唯一
 4  # saas、私有化-全域和私有化景区文旅通都显示
 5    category:
 6      - 0
 7      - 1
 8      - 2
 9    name: "页面管理"
10    sub:
11      - tag: "page_content"
12        name: "页面内容管理"
13        access:
14        - tag: "info"
15          name: "查看"
16          url:
17            - "/tourism_inner/v1/management/info"
18            - "/tourism_inner/v1/management/list"
19        - tag: "edit"
20          name: "编辑"
21          url:
22            - "/tourism_inner/v1/management/edit"
23      - tag: "page_layout"
24        name: "页面布局管理"
25        access:
26        - tag: "info"
27          name: "查看"
28          url:
29            - "/tourism_inner/v1/layout/add"
30   # 没有二级页面
31  - tag: "scenic_management"
32    name: "景区管理"
33    # 只有景区文旅通显示
34    category:
35      - 1
36    access:
37      - tag: "edit"
38        name: "编辑"
39        url:
40          - "/tourism_inner/v1/scenic/update"

角色设计

设计角色表如下:

 1CREATE TABLE `role` (
 2  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
 3  `product_id` bigint(20) NOT NULL COMMENT '产品id',
 4  `name` varchar(20) NOT NULL COMMENT '角色名',
 5  `category` tinyint(1) NOT NULL COMMENT '类型: 1全域角色 2景区角色',
 6  `content` text NOT NULL COMMENT '角色内容',
 7  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态: 1有效 0无效',
 8  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 9  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
10  PRIMARY KEY (`id`),
11  KEY `idx_product` (`product_id`)
12) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';

content:为该角色关联的模块信息,举例如下:

 1[
 2    {
 3        "tag":"page_content",
 4        "access":["info", "edit"]
 5    },
 6    {
 7        "tag":"page_layout",
 8        "access":["edit"]
 9    },
10    {
11        "tag": "scenic_management",
12        "access": ["edit"]
13    }
14]

该角色有 页面管理→页面内容管理 的查看和编辑权限,页面管理→页面布局管理 的查看权限。

用户角色关联设计

用户角色授权表为:

 1CREATE TABLE `authorization` (
 2  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 3  `authorizer_id` bigint(20) NOT NULL COMMENT '用户id',
 4  `role_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '角色id',
 5  `domain_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '全域id',
 6  `scenic_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '授权景区id,0说明为全域管理员',
 7  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:1有效 0无效',
 8  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
 9  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
10  PRIMARY KEY (`id`),
11  UNIQUE KEY `unique_authorizer` (`authorizer_id`,`domain_id`,`scenic_id`),
12  KEY `idx_domain` (`domain_id`),
13  KEY `idx_scenic` (`scenic_id`)
14) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='用户-角色授权表';

role_id 为新增字段。

登录设计

因系统分saas交付和私有化交付,两种系统登录交互差异较大,针对两种交付方式设计如下。

特别注意:因系统需要支持私有化和saas两种形式部署,为解决超管问题,默认权限表(authorization)为空标记为该产品的超级管理员。

saas

saas支持用户申请入驻产品,因此流程图较为复杂。对初次扫码的用户会自动入库(平台用户user表),并依次判断是否申请过产品、产品是否完成审批、审批后查询相关的权限(创建全域或者景区自动对该用户添加管理权限);另外也支持用户扫码申请权限。

用户入驻产品后支持创建不同角色,并绑定相关人员。

saas 内部配置平台超管权限,支持用户入驻的审核。

私有化

  1. 私有化的系统为固定类型文旅通(全域or景区),不可申请入驻。

  2. 用户首次扫码后,需要由我们开发人员操作数据库进行数据初始化,包括:产品、授权表绑定用户。

流程图如下:

其他用户扫码申请授权跟 saas 保持一致,参考上文。

参考链接

RBAC 用户、角色、权限、组设计方案

最好的权限设计,是先区分功能权限和数据权限

角色权限设计的 100 种解法

数据平台的权限设计指南