说到权限很多人都会想到RBAC,ACL等等,这些方案都是十分成熟的权限管理方案,最早写PHP用yii2框架的时候,就自带了rbac权限管理,也对rbac比较熟悉,但今天想说的不仅仅局限于路由权限。
RBAC权限管理
关于rbac权限管理gg可以出一堆文章,基于角色的访问控制,把一堆路由分配给一个角色,然后把一堆角色分配给项目中的某个人,此人即拥有这些路由的访问权限。
这里只对rbac做出简单的说明,此处不多说。
现在的矛盾来了,如果两个人People_A和People_B分别属于两个项目组Team_A, Team_B,同时这两个项目组分别拥有一条数据Data_A, Data_B,此数据有如下两条路由:
- GET /project/data 查询数据详情
- PUT /project/data 修改数据详情
People_A和People_B都拥有上述两个路由的权限,那么怎么区分二者只能操作各自组的数据Data_A和Data_B?
这里答案还是挺简单的,人与数据同时绑定了项目组,只需要判断人操作的数据是否同时属于一个项目组即可!!!
问题是否就这么简单呢?
再进一步的需求: People_A需要拥有Team_B的Data_B数据的上述两条数据权限,又该如何解决?
这个问题也比较简单,可以修改我们的业务逻辑。每个人可以属于多个组,即将People_A加入Team_B组,那么只需要在做Data_B的权限判断是判断People_A所在的所有组,只要一个组与Data_B是在一个组即可!!!
好开心呀,上述问题都解决了,是否就完了呢?
需求又来了,People_A只能拥有Team_B的Data_B数据的查询数据详情路由(GET /project/data)的权限,即People_A只能查看Data_B数据,不能修改。 这个需求如何搞?
好像现有的解决方案没法整呀!
下面进入正题,新鲜出炉的一套权限解决方案,也是我们项目经过多次权限的折腾最终总结出来的。
新权限的特点
- 路由权限的管理还是使用的RBAC
- 每条路由除了拥有路由权限,还拥有数据权限
- 为解决数据权限,每个用户可创建一个数据权限的key,我们叫做signKey
- 项目中启用数据权限的路由所操作的数据,都需要分配一个signKey
- signKey的创建者,只需要将他人加入到signKey的授权人中,并再给其分配相关数据权限的路由
说了上述几点,可能由于文字功底不足,完全听不懂,举个形象的栗子:
signKey就是一个QQ群,创建此signKey的就是群主,群主可以将数据上传到该群中,然后再拉一些人到此群中,那么这些人就能够对这些数据进行操作。同时给每个人分配的路由不一样,那么每个人对数据的操作权限也不一样,可以控制到部分人能够访问和修改数据,部分人只能访问数据而不能修改数据。
Talk is cheap, show me your code!
下面具体从数据结构层面分析,如下代码全部是golang编写,下述数据结构适用于mongodb的存储。
路由数据结构