- 也呆过几家ToB的公司,都有涉及到权限系统的设计,基本上都是基于RBAC模型。做的最好的某saas电商平台,标准的RBAC模型,完全做到了配置化,业务上无侵入,既可以可以在内部的权限平台上预设好默认的角色,saas用户可以开箱即用,也可以自定义自己的角色。
一般功能权限平台涉及这几个部分
内部权限运营平台
产品可以配置具体的权限点,前端可以配置的菜单url, 后端维护接口与其对应的权限。 产品维护默认的角色,然后将角色与权限关联起来,客服可以维护角色与用户关联。
用户端
暴露给外部用户,可以自定义角色,新建用户,将自定义角色与权限关联起来,可以将角色授权给用户。
前端
需要封装一个js的sdk, 得到整颗菜单树,树的每个节点都包含了对应的权限,根据当前用户标识,获取其拥有所有角色对应的权限,将树进行过滤,得到有权限的菜单树,进行渲染。
后端
调用某个接口的时候,获取在内部权限运营平台维护的该接口对应的权限集,根据当前用户标识,获取其拥有角色对应的权限,两者存在交集则表面有权限调用接口。
按钮等菜单子元素
也可以将其视作菜单一并处理,即在内部权限运营平台维护按钮对应的权限,和菜单一样的校验逻辑。
另类的设计
以上是做的比较规范的,扩展性也比较好,但是之前接触到的公司有些另类的做法,不知道是没理解权限还是故意这么做,而且不仅仅是一家公司这样做,在此也记录下。
没有将菜单和权限分开
只是在后台维护了菜单树,然后直接将角色和菜单关联,这样实际上将权限和菜单隐含到一张表里了,可以视为权限和菜单做了个一对一,获取权限树时只需查询用户其所有角色对应的权限,权限即菜单,也无需过滤。
按钮作为功能点额外维护
没有像上面将按钮也视为一种特别的权限菜单来做,需要额外的表和编码来做校验,实际上和菜单的逻辑一样,可以一并处理。
直接将权限授权给用户,没有经过角色。
这就相当于RBAC结合了ACL,直接给用户授权权限,当权限需要回收的时候比较蛋疼。
接口和权限一对一
之前公司的权限平台,每当注册一个接口还会生成一个权限点,将两者关联,还无法自己自定义权限,非常操蛋,不符合实际的情况。
数据权限
方案1 能够查看别人的数据
维护一个数据权限集,集合里面包含了一些用户(也可以是角色或者其他,可以扩展),每个集合还包含了使用者,含义是使用者可以查看所有权限集合里面其他用户的数据,当用户查询订单列表时,原本只是查询自己的单子,sql的where条件是 user_id in (current_user_id), 如果发现当前用户是某个权限集的使用者,则获取所有集合里面的用户id, 将sql改写成user_id in (user_id_xxx), 通过这种方式来扩大自己的权限。
方案2 能够过滤部分数据
这种方式是基于配置过滤规则,即能在某个平台配置某个表的某个字段必须等于xx, 然后动态生成sql,查询出所有满足条件的数据,在和功能权限的查询结果做协同过滤,得到一个子集,缺点是配置维护复杂,系统实现难度高,容易影响系统查询效率。适用的场景是我有查看订单的权限, 但是我只能查询某个类型的单子,那就可以配置订单表的订单类型字段必须等于xx这样的规则,这样在查询的时候会生成一个sql, select id from order where order_type=x, 在和分页查询的sql拼接, 。。。join (select id from order where order_type=x) b on a.order_id = b.id, 当然这非常影响性能,其实我觉得可以优化下,不用生成子查询,生成where条件拼接到分页查询的sql之后,不过之前公司确实是这样用的,在此记录一下。
总结
这边也只是记录一下我所学,之前公司说实话技术不是很强,权限这一块也有很大的提升空间。
参考
developers.youzanyun.com/article/155… zhuanlan.zhihu.com/p/529852735 help.fanruan.com/finebi/doc-…