美文网首页web后端
设计-RBAC数据库的设计与使用

设计-RBAC数据库的设计与使用

作者: 云龙789 | 来源:发表于2017-03-23 22:39 被阅读2193次

    文章-如何设计数据库表实现完整的RBAC(基于角色权限控制)
    【RBAC】打造Web权限控制系统

    这种关系的讲解,推荐一篇文章--[文章2]

    • 先看几张图,了解下RBAC
    权限模型

    ACL是用户直接拥有权限,RBAC是用户通过角色来拥有的权限。与权限之间是间接关系

    图片.png
    • RBAC简化了用户和权限的关系,易扩展和维护
    图片.png 图片.png 图片.png 图片.png 图片.png 图片.png

    数据库设计-- 要时刻牢记一个原则,用户是通过角色来拥有的权限。也就是用户是跟角色有关联,而跟权限没有关联

    开发之前有必要先来分析一下数据表:
    我们给角色赋权限,让角色与用户关联

    - 1.用户表--users
    - 2.权限表--permissions
    - 3.角色表--roles
    - 4.角色表和权限表--role_permission
    - 5.用户和角色表--user_role
    
    drop table `permissions` if EXISTS ;
    CREATE TABLE IF NOT EXISTS `permissions` (
      `id` int(11) NOT NULL auto_increment,
      `Title` char(64) NOT NULL,
      `Description` text NOT NULL,
      `slug` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
    `http_path` text COLLATE utf8mb4_unicode_ci,
      PRIMARY KEY  (`id`),
      KEY `Title` (`Title`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='权限表';
    
    slug表示权限的名称,比如登录
    http_path表示uri路径  比如 /login /logout
    
    drop table `roles` if EXISTS ;
    CREATE TABLE IF NOT EXISTS `roles` (
      `id` int(11) NOT NULL auto_increment,
      `Title` varchar(128) NOT NULL,
      `Description` text NOT NULL,
      PRIMARY KEY  (`id`),
      KEY `Title` (`Title`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='角色表';
    
    drop table `role_permission` if EXISTS ;
    CREATE TABLE IF NOT EXISTS `role_permission` (
      `role_id` int(11) NOT NULL,
      `premission_id` int(11) NOT NULL,
      PRIMARY KEY  (`role_id`,`premission_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='角色权限表';
    
    
    
    drop table `user_role` if EXISTS ;
    CREATE TABLE IF NOT EXISTS `user_role` (
      `user_id` int(11) NOT NULL,
      `role_id` int(11) NOT NULL,
      PRIMARY KEY  (`user_id`,`role_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='用户角色表';
    
    
    当然,还有user表。此处不再写
    `role_permission`  表里可以使用    PRIMARY KEY  (`role_id`,`premission_id`)索引。无需自增id 。`user_role`表也是一样
    在使用上:
    `user_role` 的表,哪个用户想拥有哪个菜单的角色,就在这个表添加一条数据
    `role_permission` 的表,哪个角色想拥有哪个权限,就在这个表添加一条数据
    

    这样我们只是建好了表,但实际我们是要用于某些后台连接点击权限的
    所以我们还需要两张表链接菜单表menus用户和链接菜单表role_menu

    drop table `role_menu` if EXISTS ;
    CREATE TABLE `role_menu` (
      `role_id` int(11) NOT NULL,
      `menu_id` int(11) NOT NULL,
      PRIMARY KEY  (`role_id`,`menu_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='用户和链接菜单表';
    
    drop table `menus` if EXISTS ;
    CREATE TABLE `menus` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `parent_id` int(11) NOT NULL DEFAULT '0',
      `order` int(11) NOT NULL DEFAULT '0' COMMENT '排序,这个表可以不要',
      `title` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
      `uri` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='链接菜单表';
    
    `role_menu` 的表,哪个角色想拥有哪个菜单的权限,就在这个表添加一条数据
    
    `menus表`

    再进一步想,我们可以通过管理组来与用户关联.此处的组,可以理解为上面的角色。那么我们需要如下两个表。我们给组赋权限,让组与用户关联

    drop table `groups` if EXISTS ;
    CREATE TABLE IF NOT EXISTS `groups` (
      `id` int(11) NOT NULL auto_increment,
      `Title` varchar(128) NOT NULL,
      `Description` text NOT NULL,
      PRIMARY KEY  (`id`),
      KEY `Title` (`Title`),
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='用户组表';
    
    drop table `group_permission` if EXISTS ;
    CREATE TABLE IF NOT EXISTS `group_permission` (
      `premission_id` int(11) NOT NULL,
      `group_id` int(11) NOT NULL,
      `slug` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
    `http_path` text COLLATE utf8mb4_unicode_ci,
      PRIMARY KEY  (`group_id`,`premission_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='角色组';
    
    drop table `user_group` if EXISTS ;
    CREATE TABLE IF NOT EXISTS `user_group` (
      `group_id` int(11) NOT NULL,
      `user_id` int(11) NOT NULL,
      PRIMARY KEY  (`user_id`,`group_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='角色组与用户表';
    

    第二部分,使用篇

    上面我们介绍完表关联设计后,接下来谈一谈怎么使用。使用的时候应该是某个角色role可以操作某些路由,所以应该有两个表。路由表menu和角色路由表role_menu

    CREATE TABLE `role_menu` (
      `role_id` int(11) NOT NULL,
      `menu_id` int(11) NOT NULL,
      KEY `role_menu_role_id_menu_id_index` (`role_id`,`menu_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    
    CREATE TABLE `menu` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `parent_id` int(11) NOT NULL DEFAULT '0',
      `order` int(11) NOT NULL DEFAULT '0',
      `title` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
      `uri` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    
    表单层级表

    此处我讲下路由限制的menu表,

    parent_id就是本url属于哪个层级(这里用的是无限分类)
    比如此处表单和test都在4Roles下面
    order是列表显示的排序,序号小的在上面,此处表单在test上面
    uri是角色可以访问的路由,自己通过代码限制即可
    menu与role_menu`表的配合是指图中最坐变那排图标的显示

    然后是 permissionsslughttp_path字段也是路由限制,permissions是表示直接在浏览器上输入路由不可以访问

    要说明的是,如果不显示图标的情况,如果你没做路由访问限制,输入对应的uri其实也是可以访问页面的。

    我们在显示某个用户的菜单列表的时候,
    role_menu表中,role_id,menu_id都可以是多个
    1.通过user.id查到role_menu.menu_id集合
    2.然后查到符合menu_id集合的menu.id显示出来

    在做某个用户访问某个路由的时候
    role_user表中user_id是唯一的,role_id是可以多个的
    1.通过user.id得到role_user.role_id
    2.然后得到role_permissions表中的permissions.(表中的permissions_id和role_id都可以是多个)
    3.去permissions表取出id对应的uri(即http_path)数据

    相关文章

      网友评论

      • 4b3b5de027b7:权限表里的 title 和 slug 这两个区别是什么 ? 有点没搞懂 方便的话可以提供两条权限表的数据记录么 ?
        云龙789:@扑倒萌受 title和slug其实分别是中英文权限名称。比如id 1代表manager 经理。slug只是给操作员看的名字。其实也可以不用英文,直接一个中文即可。我是看大多都用了中英,就写上了。其实这个无所谓,起作用的还是role_permission这个关联表
      • 042a0e1be73f:请问用户怎样和数据权限关联?
        云龙789:更新了
        云龙789: @iOSwift 可以将role表调节一个路由。将不同路由按照角色,做成层级式的。根据权限,显示当前权限的最高路由。
      • df1483a56565:菜单应该和权限关联吧,不然怎么用权限控制?
        云龙789:更新了
        云龙789:@死大蒜 是的 有关系

      本文标题:设计-RBAC数据库的设计与使用

      本文链接:https://www.haomeiwen.com/subject/izktottx.html