2025年rbac权限设计(rbac权限管理设计案例)

rbac权限设计(rbac权限管理设计案例)在绝大部分的微服务平台中 都会涉及到账号表 account 用户表 user 用户组表 user group 角色表 role 和权限表 permission 等的通用数据表 然而这几张表之间又会存在一些非常通用的关系以及相同的处理方式 本文将基于角色访问控制 Role Based Access Control 来设计一个通用 用户角色权限 平台

大家好,我是讯享网,很高兴认识大家。



在绝大部分的微服务平台中,都会涉及到账号表(account)、用户表(user)、用户组表(user_group)、角色表(role) 和权限表(permission)等的通用数据表,然而这几张表之间又会存在一些非常通用的关系以及相同的处理方式。本文将基于角色访问控制(Role-Based Access Control)来设计一个通用“用户角色权限”平台,该设计可以非常好地被移植至各类微服务项目中。

RBAC(Role-Based Access Control)

RBAC(基于角色的访问控制)是指用户通过角色与权限进行关联。即一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户—角色—权限”的授权模型。在这种模型中,用户与角色之间、角色与权限之间,一般者是多对多的关系。

本节主要介绍一个能在生产环境使用的用户角色权限管理平台。

在我们的系统中,会有各种各样的登录方式,如手机号、邮箱地址、身份证号码和微信登录等。因此该表主要是用来记录每一种登录方式的信息,但不包含密码信息,因为各种登录方式都会使用同一个密码。每一条记录都会关联到唯一的一条用户记录。

CREATE TABLE account  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘账号ID’,  user_id bigint(20) NULL DEFAULT NULL COMMENT ‘用户ID’,  open_code varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘登录账号,如手机号等’,  category tinyint(1) NULL DEFAULT NULL COMMENT ‘账号类别’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted double(1, 0) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX idx_member_id(user_id) USING BTREE COMMENT ‘普通索引’,  CONSTRAINT account_ibfk_1 FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = ‘账号’ ROW_FORMAT = Dynamic;

主要是用来记录用户的基本信息和密码信息。其中禁用状态(state)主要是在后台管理控制非法用户使用系统;密码加盐(salt)则是用于给每个用户的登录密码加一把唯一的锁,即使公司加密公钥泄露后,也不会导致全部用户的密码泄露。

CREATE TABLE user  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘用户ID’,  state tinyint(1) NULL DEFAULT NULL COMMENT ‘用户状态:0=正常,1=禁用’,  name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘姓名’,  head_img_url varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘头像图片地址’,  mobile varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘手机号码’,  salt varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘密码加盐’,  password varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘登录密码’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘用户’ ROW_FORMAT = Dynamic;

用户账号表(account)和用户表(user)组合在一起,就完成了用户账号模块的设计。如果还想再细分,则可以将两张表拆为以下三张表:

当然,如果用户信息的字段太多,则可以适当拆分为多张不同领域的用户信息表,这里不再介绍。


讯享网

有了用户之后,我们希望不同的用户能操作和查看不同的功能(如页面、菜单和按钮等)。因此需要定义一张表来存储权限相关的信息。包括权限之前还有父子关系,分配了父级后,应该拥有所有的子级权限。同时权限的信息也会分配至前端页面来控制,因此需要提供一个唯一标识(code),有人会问 id 不行吗?当然可以,只是我们的 ID 是自动生成,每个环境都不一样,重新生成后也不一样,因此才单独使用了一个字段来标识。

CREATE TABLE permission  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘权限ID’,  parent_id bigint(20) NULL DEFAULT NULL COMMENT ‘所属父级权限ID’,  code varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘权限唯一CODE代码’,  name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘权限名称’,  intro varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘权限介绍’,  category tinyint(1) NULL DEFAULT NULL COMMENT ‘权限类别’,  uri bigint(20) NULL DEFAULT NULL COMMENT ‘URL规则’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX parent_id(parent_id) USING BTREE COMMENT ‘父级权限ID’,  INDEX code(code) USING BTREE COMMENT ‘权限CODE代码’ ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘权限’ ROW_FORMAT = Dynamic;

其实,再加一张 用户权限表(user_permission) 即可组成一个用户权限中心了,但这样做是不好的。比如我们设想:有 200 个权限点,1 亿个用户,每个人平均配置 100 个权限,则 user_permission 表将会有 100 亿条记录,而且每当我们新增 1 个权限点时,可能需要添加上亿条记录。简而言之会有以下弊端:

因此,我们会引入一张角色表(role)来解决问题。

为了解决维护起来方便,我们会对权限表中的记录进行分组,将相关的一些权限分配为同一组,称之为角色。角色表的作用是为了将零散的权限进行聚合,然后方便对相关的一组进行统一处理(即小范围批量处理)。该表的增加可谓是大大减少了上述维护困难的问题。

CREATE TABLE role  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘角色ID’,  parent_id bigint(20) NULL DEFAULT NULL COMMENT ‘所属父级角色ID’,  code varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘角色唯一CODE代码’,  name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘角色名称’,  intro varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘角色介绍’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX parent_id(parent_id) USING BTREE COMMENT ‘父级权限ID’,  INDEX code(code) USING BTREE COMMENT ‘权限CODE代码’ ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘角色’ ROW_FORMAT = Dynamic;

该表主要是用来存储每个用户拥有哪些角色。一般情况,每个用户只会有几个角色,因此数据量从 100 亿变成 10 亿或更少。

CREATE TABLE user_role  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘ID’,  user_id bigint(20) NULL DEFAULT NULL COMMENT ‘用户ID’,  role_id bigint(20) NULL DEFAULT NULL COMMENT ‘角色ID’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX member_id(user_id) USING BTREE COMMENT ‘用户ID’,  INDEX role_id(role_id) USING BTREE COMMENT ‘角色ID’,  CONSTRAINT user_role_ibfk_1 FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE RESTRICT ON UPDATE RESTRICT,  CONSTRAINT user_role_ibfk_2 FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘用户角色’ ROW_FORMAT = Dynamic;

该表则是用来定义每个角色组中有哪些权限。该表的数量则更少(基本都在 1 万条以内)。

CREATE TABLE role_permission  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘ID’,  role_id bigint(20) NULL DEFAULT NULL COMMENT ‘角色ID’,  permission_id bigint(20) NULL DEFAULT NULL COMMENT ‘权限ID’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX role_id(role_id) USING BTREE COMMENT ‘角色ID’,  INDEX permission_id(permission_id) USING BTREE COMMENT ‘权限ID’,  CONSTRAINT role_permission_ibfk_1 FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE RESTRICT ON UPDATE RESTRICT,  CONSTRAINT role_permission_ibfk_2 FOREIGN KEY (permission_id) REFERENCES permission (id) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘角色权限’ ROW_FORMAT = Dynamic;

总结一下,本节所说的精简版代表的是,能在线上运行的表设计(4 张实体表和 2 张中间表),虽然使用 account、user、permission、user_permission 也能用,但基本没人会这样来用的,因为对后期维护起来很麻烦,数据量也很庞大。

本节是在上述 6 张表的基础上进行再次优化设计延伸。

上述虽然增加了角色表(role)后,把数据量从 100 亿降低至 10 亿,但 10 倍的数据量依然还是很多。而且大部分的用户(主体用户。如学生系统,学生就是主体)都会分配相同的角色组。用户组和角色组的区别:

CREATE TABLE user_group  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘ID’,  parent_id bigint(20) NULL DEFAULT NULL COMMENT ‘所属父级用户组ID’,  name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘用户组名称’,  code varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘用户组CODE唯一代码’,  intro varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘用户组介绍’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX parent_id(parent_id) USING BTREE COMMENT ‘父级用户组ID’,  INDEX code(code) USING BTREE COMMENT ‘用户组CODE代码’ ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘用户组’ ROW_FORMAT = Dynamic;

该表用来记录每个用户组下有哪些用户。

CREATE TABLE user_group_user  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘ID说’,  user_group_id bigint(20) NULL DEFAULT NULL COMMENT ‘用户组ID’,  user_id bigint(20) NULL DEFAULT NULL COMMENT ‘用户ID’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX member_group_id(user_group_id) USING BTREE COMMENT ‘用户组ID’,  INDEX member_id(user_id) USING BTREE COMMENT ‘用户ID’,  CONSTRAINT user_group_user_ibfk_1 FOREIGN KEY (user_group_id) REFERENCES user_group (id) ON DELETE RESTRICT ON UPDATE RESTRICT,  CONSTRAINT user_group_user_ibfk_2 FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘用户组成员’ ROW_FORMAT = Dynamic;

该表用来记录每个用户组下拥有哪些用户角色。

CREATE TABLE user_group_role  (  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘ID’,  user_group_id bigint(20) NULL DEFAULT NULL COMMENT ‘用户组ID’,  role_id bigint(20) NULL DEFAULT NULL COMMENT ‘角色ID’,  created datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,  creator varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘创建人’,  edited datetime(0) NULL DEFAULT NULL COMMENT ‘修改时间’,  editor varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘修改人’,  deleted tinyint(1) UNSIGNED ZEROFILL NULL DEFAULT 0 COMMENT ‘逻辑删除:0=未删除,1=已删除’,  PRIMARY KEY (id) USING BTREE,  INDEX member_group_id(user_group_id) USING BTREE COMMENT ‘用户组ID’,  INDEX role_id(role_id) USING BTREE COMMENT ‘角色ID’,  CONSTRAINT user_group_role_ibfk_1 FOREIGN KEY (user_group_id) REFERENCES user_group (id) ON DELETE RESTRICT ON UPDATE RESTRICT,  CONSTRAINT user_group_role_ibfk_2 FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘用户组角色’ ROW_FORMAT = Dynamic;

每个系统主体用户,基本都占用了所有用户的 90% 以上(既包含用户,又包含商家的系统,用户和商家同时都是主题用户)。因此,每个用户注册时,基本只需要分配一条所属的用户组,即可完成角色权限的配置。这样处理后,数据量将从 10 亿下降至 1 亿多。同时也减少了用户注册时的需批量写入数量。

小讯
上一篇 2025-05-07 20:45
下一篇 2025-06-15 15:19

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/139080.html