美文网首页
3+1 张表建立一个强大的RBAC鉴权管理系统

3+1 张表建立一个强大的RBAC鉴权管理系统

作者: sowork | 来源:发表于2019-01-23 18:25 被阅读134次

    讲在前面的

    我们一般在开发后台管理应用程序的时候,或多或少都会涉及到鉴权管理。鉴权管理中一般有角色、权限两部分组成,用户直接和角色关联,这种鉴权管理实现简单,在一些较小的项目中也比较容易实现,但是在一些比较大的项目中就有些局限性了,或者说对权限的要求更高、更细粒度。下面我主要讲下如果通过3+1来实现鉴权管理。


    3 指的是3张鉴权表设计

    • yauth_items,这张表记录的是鉴权节点表,表结构如下:
    CREATE TABLE `yauth_items` (
        `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `item_code` VARCHAR(191) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `client_id` INT(10) UNSIGNED NULL DEFAULT NULL,
        `user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
        `item_name` VARCHAR(191) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `item_desc` VARCHAR(191) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `item_type` TINYINT(3) UNSIGNED NOT NULL,
        `scope` VARCHAR(191) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `other_data` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `deleted_at` TIMESTAMP NULL DEFAULT NULL,
        `created_at` TIMESTAMP NULL DEFAULT NULL,
        `updated_at` TIMESTAMP NULL DEFAULT NULL,
        PRIMARY KEY (`id`),
        UNIQUE INDEX `yauth_items_item_code_unique` (`item_code`)
    )
    COLLATE='utf8mb4_unicode_ci'
    ENGINE=InnoDB;
    
    • yauth_item_relation,这张表记录的是鉴权节点之间的层级关系
    CREATE TABLE `yauth_item_relation` (
        `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `item_id` INT(10) UNSIGNED NOT NULL,
        `client_id` INT(10) UNSIGNED NOT NULL,
        `scope` VARCHAR(191) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `parent_id` INT(11) NULL DEFAULT NULL,
        `lft` INT(11) NULL DEFAULT NULL,
        `rgt` INT(11) NULL DEFAULT NULL,
        `depth` INT(11) NULL DEFAULT NULL,
        `deleted_at` TIMESTAMP NULL DEFAULT NULL,
        `created_at` TIMESTAMP NULL DEFAULT NULL,
        `updated_at` TIMESTAMP NULL DEFAULT NULL,
        PRIMARY KEY (`id`),
        INDEX `yauth_menus_item_id_index` (`item_id`),
        INDEX `yauth_menus_parent_id_index` (`parent_id`),
        INDEX `yauth_menus_lft_index` (`lft`),
        INDEX `yauth_menus_rgt_index` (`rgt`)
    )
    COLLATE='utf8mb4_unicode_ci'
    ENGINE=InnoDB;
    
    • yauth_item_group,这张表是记录鉴权节点之间的依赖关系
    CREATE TABLE `yauth_item_group` (
        `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `parent_id` INT(10) UNSIGNED NOT NULL,
        `child_id` INT(10) UNSIGNED NOT NULL,
        `client_id` INT(10) UNSIGNED NOT NULL,
        `scope` VARCHAR(191) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `deleted_at` TIMESTAMP NULL DEFAULT NULL,
        `created_at` TIMESTAMP NULL DEFAULT NULL,
        `updated_at` TIMESTAMP NULL DEFAULT NULL,
        PRIMARY KEY (`id`),
        INDEX `yauth_item_relation_parent_id_index` (`parent_id`),
        INDEX `yauth_item_relation_child_id_index` (`child_id`)
    )
    COLLATE='utf8mb4_unicode_ci'
    ENGINE=InnoDB;
    

    1 指的是用户分配(关联)表设计

    • yauth_assignments,这张表指的是用户和鉴权节点如何进行分配(关联)
    CREATE TABLE `yauth_assignments` (
        `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `item_id` INT(10) UNSIGNED NOT NULL,
        `user_id` INT(10) UNSIGNED NOT NULL,
        `provider` VARCHAR(191) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `deleted_at` TIMESTAMP NULL DEFAULT NULL,
        `created_at` TIMESTAMP NULL DEFAULT NULL,
        `updated_at` TIMESTAMP NULL DEFAULT NULL,
        PRIMARY KEY (`id`),
        INDEX `yauth_assignments_user_id_index` (`user_id`),
        INDEX `yauth_assignments_item_id_index` (`item_id`)
    )
    COLLATE='utf8mb4_unicode_ci'
    ENGINE=InnoDB;
    

    简单说下鉴权管理的思路

    • 一切皆节点,节点包括权限、菜单、角色等等
    • 节点之间没有显示的层级关系,比如菜单包含权限,角色包含权限,但是权限不能包含菜单,这个需要根据需求在代码里面实现
    • 权限、菜单、角色三者之间的关系如下,并且同级之间也可以相互包含,比如角色A包含角色B,当然,你可以根据自己的需求代码里面去控制


      权限、菜单、角色关系
    • 我把4张表的一个ER图大概画了一下,标注了里面节点的一些含义


      表之间的关联关系

    下面解读下表结构

    yauth_items表 = 权限条目表

    • item_code = 节点代码 // 用来做唯一标识
    • client_id = 客户端ID // 用来标识是哪个客户端访问过来的用户,你总不想每做一个客户端都写一套rbac系统吧,比如有clientAclientB,业务功能不同,权限也不同,通过client_id我们就能根据client找到该机构下拥有的权限,来判断权限该用户是否有权限
    • user_id = 用户ID
    • item_name = 节点名称 // 比如该节点是一个菜单、它的名字叫 首页
    • item_desc = 节点描述 // 给节点添加更详细的描述信息
    • item_type = 节点类型 // 节点的类型 权限、菜单、角色,可以根据需要扩充
    • scope = 作用域 // 将这些节点进行作用域划分,比如同样是菜单,分为顶部菜单和左侧菜单,多个作用域用逗号隔开,比如超管的菜单和机构的菜单
    • other_data = 其他数据// 扩展字段,我们可以为某些节点添加一些别的标识以便做特殊处理

    yauth_item_relation表 = 节点关系表

    • item_id = 节点id // 对应yauth_items表id
    • client_id = 客户端ID // 同上,标识归属于哪个客户端
    • scope = 作用域 // 该节点属于哪个作用域,单一作用域
    • parent_id = 父id // 关联本表的id字段
    • lft = 左值 // 详情可见左右值算法
    • right = 右值 // 详情可见左右值算法
    • depth = 层级 // 代表该节点的层级深度

    yauth_item_group表 = 节点分组表

    • parent_id = 父ID // 关联yauth_items表的id字段
    • child_id = 子ID // 关联yauth_items表的id字段
    • client_id = 客户端ID // 区分客户端
    • scope = 作用域 // 建立依赖时,在哪个作用域范围添加的

    yauth_assignments = 权限分配表

    • item_id = 节点ID // yauth_items表id
    • user_id = 用户ID //
    • provider = 用户提供这 // 用来标识是哪个表提供的用户,适用于多表用户

    总结:

    • yauth_items 用来存储节点,我们添加的所有节点都在这样表中
    • yauth_item_relation 用来表示节点的层级关系,不然我们看到视图不够直观。注意,添加到yauth_items表是第一步,我们将节点挂载到yauth_item_relation表,才应该生效
    • yauth_item_group 用来标识节点之间的依赖关系,角色A依赖角色B,角色B依赖菜单A、菜单B,菜单A依赖权限A,给用户分配了角色A相当于拥有了角色B、带单A、菜单B、权限A
    • 这套设计操作起来可能会比较麻烦,比如添加权限这个操作,需要先添加、在挂载、在添加依赖,不过权限这个东西本来不就随着业务要求越高越复杂么
    • 在依赖判断时,yauth_item_group表parent_id 和 child_id 递归查找依赖关系,可能会导致大量递归,使用左右值又丧失了依赖的优点,暂时没有想到好的解决办法

    相关文章

      网友评论

          本文标题:3+1 张表建立一个强大的RBAC鉴权管理系统

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