9.5 授权系统

授权系统几乎所有业务系统都会用到,所以可以单独开一章来讲。

目录

授权的原理
基于用户的授权
基于角色的授权
基于用户或者角色的授权
如何选择
拓展思考

授权的原理

每个用户拥有一系列“权限”,用户在登录之后,访问页面/接口,系统会根据登录用户查询其权限列表,检查是否具有访问目标页面/接口的权限。如果有访问权限,则访问成功,如果没有访问权限,则弹出提示“没有访问权限”。

授权系统可以分为基于用户的授权基于角色的授权基于用户或者角色的授权。下面分别讲一下。

基于用户的授权

基于用户的授权最简单,一张用户表,一张用户权限表。

用户表:存储用户信息   
用户权限表:存储用户id和权限      

举个栗子,用户表有一条记录为“Lulu”,id为1。在用户权限表中添加一条记录,用户id为1,权限为“GetData”。则用户Lulu拥有了“GetData”的权限。
她是怎么拥有权限的呢?当然不是存在数据库里面就完事了。在调用需要“GetData”权限的“GetDataApi”接口的时候,在访问GetDataApi之前,通过程序,查询登录用户Lulu的权限列表,查询到了“GetData”权限,Lulu就通过了权限验证。如图所示:

按照授权的原理,上述是最简单的方式,用户直接拥有权限。
也可以设计成一张用户表,一张权限表,一张用户权限表。因为用户可以拥有多个权限,同一权限也可以被多个用户拥有,用户和权限是多对多的关系。在设计成用户表-用户权限表-权限表时,权限的内容,比如“GetData”存储在权限表,用户权限表仅存储用户id和权限id,作为二者之间的中间表。如图所示:

基于用户的授权可以实现授权的基本需求,但是存在一些麻烦的问题:比如一个小区的安保问题,每个保安应该有100个权限,包括小区大门、各单元大门、防火栓等地方的门禁——好嘛,每次有保安入职,都要为他配置这100个权限,还不能勾错,这不是折腾人么!再想想,因为某些现实原因,需要临时开启或关闭某个地方的门禁,所以我们需要给每个保安重新配置这个权限,真是满满的工作量啊!
我们似乎需要有一个可以抽象出保安群体,为他们统一配置权限的东西,这就是第二种授权方式——基于角色的授权

基于角色的授权

这种方式我们引入一个新的概念“角色”。我们不再单独为某个用户发放权限,而是给角色配置权限,再把用户和角色匹配起来。
继续小区的话题,我们将所有保安的权限,用“保安角色”进行统一管理,为“保安角色”配置权限,而将每个保安与“保安角色”挂钩,则每个保安会获得“保安角色”所拥有的权限。说起来似乎有些饶,直接看图!
我们需要一张用户表,一张角色表,一张用户角色表,一张角色权限表。像这样:

如此,我们想要新增、删除某个保安的权限,只需要修改用户角色表。我们想要修改“保安角色”的权限,只需要修改角色权限表
需要注意的是,用户、角色必须是一对多的关系,比如一个保安既可能是安保人员,也可能是“主任”这种管理人员,则他应该拥有“保安”和“主任”两种角色都有的权限。
当然,我们也可以基于“基于用户的授权”的第二种方式,把角色-权限这部分拆的更细:

基于角色的授权是一种比较好的实现授权的方式,但它似乎不够灵活。想一想,在销售行业,同一职级的工作者,也可以有不同范围的权限。在“基于角色的授权”中,我们只能通过创建两个角色“XX职级角色1”和“XX职级角色2”来实现——很丑,对不对,而且如果这个行业需要更加灵活的权限配置,“基于角色的授权”似乎不能满足需求。
那我们就回归“基于用户的授权”?想想就觉得不科学,这时候就可以出现一种结合上述二者,取其精华去其糟粕的方式了——基于用户或者角色的授权

基于用户或者角色的授权

在这种授权方式下,我们既可以通过“用户”去授权,也可以通过“角色”去授权。所以我们可以通过“角色”为用户配置具有普遍性的权限,而通过“角色授权”为个别特殊用户单独授权。如此,来解决统一授权和特殊授权的问题。
我们需要一张用户表,一张角色表,一张用户角色表,一张用户/角色权限表。

如图所示,保安1拥有“保安角色”的所有权限,同时拥有特殊权限“特殊门门禁权限”,而保安2仅拥有“保安角色”的权限。
当然,我们依然像之前一样,可以把角色-权限这部分拆分出来.

如何选择

一句话,“根据业务”,还有个人习惯,当然要灵活可变,肯定还是选择基于用户或者角色的授权
以上只是比较普遍的授权系统设计方式,根据具体需求的不同,可能还需要进行新的设计,这也是计算机的魅力所在。同一份问卷,不同的人也可以交出不同的解答,当然它们都是非常优雅的解答:)

拓展思考

1.像金字塔一样的授权模式,应该如何去设计?
比如,政府机构:A省有权利查询A省下面所有市的数据;A省下面有个B1市,B1市有权利查询B1市下所有区的数据;B1市下面有个C1区,C1区有权利查询C区下面所有街道办的数据.......
它们大概是这样的:

这样用我们上述的设计是行不通的,我们需要组织单元
2.不同用户之间的数据相互独立
这种比较常见于软件是某项工具的情况下,比如云盘(在不考虑资源实际存储方式的情况下)。
每个用户的操作内容几乎是一样的,但他们的数据是“隔离”的,在没有该用户的授权(分享)情况下,其他用户无法获得该用户的任何资源。
这种时候怎么办呢?我们可以采用多租户

posted @ 2020-03-08 16:46  Lulus  阅读(1400)  评论(1编辑  收藏  举报