一种通用型的权限系统设计

栏目: 后端 · 前端 · 发布时间: 6年前

内容简介:30 Sep 2018 - h3l先简单看一下简单的表结构以及表关系。上述的那么多表,其实只是解决了一个问题『

30 Sep 2018 - h3l

[+] Author: h3l
[+] Team: n0tr00t security team 
[+] From: https://www.n0tr00t.com
[+] Create: 2018-09-30

先简单看一下简单的表结构以及表关系。

+----------+  parent_id & child_id    +--------------+
                               | Relation | ------------------------ | Organization |
                               +----------+                          +--------------+
                                                                       |
                                                                       | org_id
                                                                       |
                               +----------+  user_id                 +--------------+
                               |   User   | ------------------------ | UserPosition |
                               +----------+                          +--------------+
                                                                       |
                                                                       | group_id
                                                                       |
+-----+  service_id & api_id   +----------+  group_id & service_id   +--------------+
| Api | ---------------------- | Service  | ------------------------ |    Group     |
+-----+                        +----------+                          +--------------+

表解释

  • 用户相关
    • User 用于存储用户信息,主要字段为 id 用户信息等
  • 组织相关
    • Organization 用于存储组织架构中的单个组织,主要字段为 id , name 等等
    • Relation 用于存储组织架构中的组织间关系,主要字段为 parent_id , child_id
  • 群组相关
    • Group 用于存储群组信息,主要字段为 id 群组名等
    • Service 用于存储服务信息,主要字段为 id 服务名称等
    • Api 用于存储接口信息,主要字段为 id , url_name, app_name`等
    • 另外还有两张表用于存储 GroupService 的多对多关系以及 ServiceApi 的多对多关系
  • 将上述关系组织到一起
    • UserPosition 记录一个人在哪些组织上属于什么群组,主要字段有 user_id , group_id , org_id

概述

上述的那么多表,其实只是解决了一个问题『 一个人什么范围 能做 什么事情 』。

  • 一个人 即 用户相关的表
  • 什么范围 即 组织相关的表
  • 什么事情 即 群组相关的表

用户相关

即权限系统中的用户,并无复杂概念

组织相关

现实生活中的组织架构是一个类似树形的不规则结构,如下图所示

+----------+
                   +------------- |   root   | ------+
                   |              +----------+       |
                   |                |                |
                   |                |                |
                   v                v                |
                 +----------+     +----------+       |
  +------------- |  mid_a   |     |  mid_b   |       |
  |              +----------+     +----------+       |
  |                |                |                |
  |                |                |                |
  v                v                v                v
+----------+     +----------+     +----------+     +----------+
| bottom_a |     | bottom_b |     | bottom_c |     | bottom_d |
+----------+     +----------+     +----------+     +----------+

如果是存储树形结构,第一反应可能是在每个节点记录一个 parent_id 。这是最简单的做法,但是在查询某个节点的所有子节点的时候却是效率最差的做法。

这里我们采用的方法是单独拿一张关系表记录父节点到所有子节点的数据。这样做的好处是查询效率非常高,只是在插入数据的时候稍微慢一点,但是考虑到我们的应用是读大于写,所以这样做并无不妥。按照上述说法,则可以用下表表示下图。

+------+
                   +------------- | root | ------+
                   |              +------+       |
                   |                             |
                   |                             |
                   v                             |
                 +----------+                    |
  +------------- |  mid_a   |                    |
  |              +----------+                    |
  |                |                             |
  |                |                             |
  v                v                             v
+----------+     +----------+                  +----------+
| bottom_a |     | bottom_b |                  | bottom_d |
+----------+     +----------+                  +----------+
父节点 子节点
root mid_a
root bottom_a
root bottom_b
root bottom_d
mid_a bottom_a
mid_a bottom_b

tip: 如果为了方便,可以为每个节点插入一条父节点和子节点均为自己的记录。

该方法并非独创,详细的分析该方法以及与其他方法的对比可参见 https://www.slideshare.net/billkarwin/models-for-hierarchical-data

群组相关

在群组这部分的设计中,包含了五张表。但是关键的概念仅为 Api , Service , Group , 其实这样设计会稍显复杂。那我们为什么要这样设计呢?

最重要的原因是将开发与产品/运营间有效的隔离开。

Api 表记录的是系统中所有的接口,这是开发需要维护的部分。

Service 表记录的是系统中的功能点,这是需要产品/运用同开发共同维护的部分

  • 产品需要提供要在管理后台中功能点的管理粒度,比如说是:用户管理(包含用户查看,用户删除,用户修改等功能)还是用户查看?
  • 开发则需要将 Api 中与产品定义好的 Service 关联起来。

Group 表记录的是系统中的群组,这是需要产品维护的部分,同时产品需要维护群组与功能点的关系。

ps: Api 表中的 app_nameurl_name 是为了保证在不同系统中相同的 url_可能会冲突的情况

pss: 仔细想想,Api 表中的 api 是不是可以偷懒的整个一个系统只用同一个呢?甭管你有多少接口,全部一把梭,都用同一个 api 。当然可以了,只要能满足需求, api 怎么记录完全看你自己,这也是本系统灵活的原因。

n more thing

  • 是不是可以将组织架构依赖公司内部的 hr 系统?这样公司组织架构变动的时候就不用手动维护了。
  • 是不是可以将用户表也通过对接公司内部的 hr 系统来完成呢?比如对接一个 oauth,这样这个人离职/入职也不用维护这部分内容了。
  • 用户岗位部分是不是可以通过上一步介入的 oauth 拿到用户的岗位信息?通过一个员工岗位与系统内群组的对应关系的表,是不是就可以自动的让用户登录后拥有相应权限了?
  • 用户岗位部分是不是可以支持手动添加岗位?只要通过添加一个字段表示这个岗位是自动同步的还是手动加入的,自动同步的每次登录的时候刷新,非自动同步的只能手动修改。这样谁谁谁要临时加一个权限,也不用头疼了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据密集型应用系统设计

数据密集型应用系统设计

Martin Kleppmann / 赵军平、李三平、吕云松、耿煜 / 中国电力出版社 / 2018-9-1 / 128

全书分为三大部分: 第一部分,主要讨论有关增强数据密集型应用系统所需的若干基本原则。首先开篇第1章即瞄准目标:可靠性、可扩展性与可维护性,如何认识这些问题以及如何达成目标。第2章我们比较了多种不同的数据模型和查询语言,讨论各自的适用场景。接下来第3章主要针对存储引擎,即数据库是如何安排磁盘结构从而提高检索效率。第4章转向数据编码(序列化)方面,包括常见模式的演化历程。 第二部分,我们将......一起来看看 《数据密集型应用系统设计》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具