通用版的权限验证领域模块设计
背景
这里是根据我以往的经验,针对一般情况的用户登录的领域设计,理想情况下一个比较简单的领域设计。
需求:
- 有多个系统
- 不同的系统都有各自的菜单和按钮
- 不同的按钮可以根据不同的角色绑定或者和不同的用户绑定(这里就忽略了角色)
设计
本文进行的是最简单的系统声明设计。读者可以根据自己的需要区拓展表的字段。
多个系统
菜单和按钮
角色和按钮
角色和用户之间
用户属于用户领域,按照界限上下文权限领域也是属于用户领域下的,所以划分了权限领域,那么用户领域肯定不能掺杂进来。
上面是比较标准的过程,但是实际情况往往更加复杂。
我下面举几个例子拓展一下上面的领域设计。
假如我对性能要求很高,并且我的数据量很大,几亿个用户,而且要满足我旗下的员工或者我授权的某个人,关系亲近的人,还有我所有的顾客快速登录,获取权限的需求。那么我可以做如下修改:
首先角色的权限是改动较少的部分,另外大数据量的时候我们往往会分库分表,分库分表的同时也会带了了中间表较难处理的问题,针对这个问题要解决就需要做异构索引表,但是如果我们使用了以上的方式,就可以巧妙地避开这个问题。
上面的方法就是把所有的按钮放在一个镜像(即某个时刻数据的样子,也称之为数据快照)中,存成一个json字符串即可。
同理,针对一个用户可以有多个角色,高性能这种做法,也需要做如下动作:
这里我可以使用用户id做分库分表的拆分键,就算我有几个亿的用户,但是外部拿这个userId来这里查这个人的权限的时候,相信也不会慢。
要满足旗下员工登录 这个需求比较特殊,在设计系统的时候,单表其实是最好提高性能的手段,所以要满足登录的高性能,建议维护一张用户登录表。这张表的数据量会很大,现在假设有几个亿。
假设我的系统有多个登录手段:
- 我的用户直接登录,用手机号码或者卡号
- 我的妻子可以登录,用我的卡号,加载出她的手机号码,然后登录
- 我个人可以用手机号码登录,也可以用卡号登录
- 我的员工可以用我的卡号,加载出所有员工的卡号,再登录
针对这种需求,我会设计两张表:
- 通过卡号登录
上面是员工较少的做法,如果员工过多,其实不会有下拉这种需求,也没有客户会从10000个员工里面选出自己。如果员工过百,过千建议上表放到mongo db中。 - 通过手机号码登录
通过卡号登录:只能是用户自己登录,可以使用卡号去做卡号登录表的拆分键,从而提高性能。
通过手机登录:通过卡号去卡号登录表找出这个卡号关联的手机号码有哪些,关联的phone对应的user_id有哪些。然后再到手机登录表中验证,是否可以登录。
以上两个方式都是获取到userId,然后使用userId去获取用户权限。
权限控制的性能优化方向可以考虑将哪些常用的数据放入redis中,再做一层ehcache。比如登录表最近使用的1000w个用户数据(LRU算法。)。
还有就是可以充分利用mongodb,尽量使设计简单化。
理想化的权限控制中心,最好带一个可视化的界面,并且支持导出数据,从而提高团队其它成员的开发效率。