前言
用户源代码可以在 snapper-dependence 中进行查看
用户是每一个权限系统的核心点,权限系统的权限控制最终控制的是用户,从资源权限上控制功能是否可操作,从数据权限上控制用户能查看哪些数据。本章我们讨论用户的设计。
用户设想
按照以往的原则,先头脑风暴一番,分两个维度来考虑
- 用户属性设计 所涉及的属性:用户名、密码、手机号、邮箱、ID等等
- 用户功能设计 管理功能(增删改查)、修改密码、重置密码、停用等等
最终一番构思后形成了如下花型图

通过花型图我们总结下:
- 属性中绿色 部分是系统所必需的,黄色部分 为业务所需的,红色部分 是用于策略控制的,虚线部分是可选的,比如头像涉及到图片的存储,需要引入文件存储的中间件,暂时不深入讨论。
- 功能中橙色部分 是系统所必需的管理功能,红色部分 是状态控制,蓝色部分 是密码相关,绿色部分是权限相关
花型图中绿色部分只有 资源权限,主要是针对离散的权限需求,让用户直接分配资源权限;数据权限和角色资源授权后续讨论。
为方便管理,将权限分配类型分为离散型 和聚集型,具体如下:
- 离散型 是指权限分配针对用户比较分散,比如A用户需要下单功能、B用户需要财务功能、C用户需要分析功能等等,在权限上分散,如果要建立角色再分配会创建很多角色,管理起来也不简洁
- 聚集型 指通常的按照角色分配的类型,权限比较聚集,比如财务的角色拥有统一财务的功能、客服角色拥有客服对应的功能
用户属性
花型图中罗列的用户属性仅满足权限系统的设计需要,对于特定的业务在此不讨论。属性设计主要说明如下:
- ID 主要用来服务框架的,为框架提供统一的处理,比如通用的增删改查功能,针对分库分表有特殊的意义
- 用户名 要求唯一性不能重复,前面章节中的登录,需要以用户名查询是否存在,注册时同样需要,为提高效率此字段可以添加上对应的索引
- 密码 登录验证必须,需密文存储,加密方式依赖于登录密码匹配模式
- 状态 用来控制用户的状态,便于状态流的处理,在业务逻辑中尤为重要
- 邮箱 主要用来发送初始密码信息,系统生成随机密码发送到用户邮箱或注册时的验证码及邮箱验证
- 手机号 用来绑定微信或者手机号码方式登录及其他相关安全验证
- 姓名 用户的真实姓名,在日志审计及追踪中展示或者业务操作中需要
- 头像 因存储问题,当前暂不讨论,预留字段
- 允许终端 参考前面登录章节的内容,此处可配置用户允许哪些终端登录,终端来自于字典数据,可以为某一个终端登录页面设置对应的终端信息,登录提交时提交对应的终端信息,也可以通过User-Agent信息来自行判断
- 是否同时登录 前面登录章节约定不同的终端是允许同时登录,此处的同时登录是针对相同的终端
- 过期策略 TOKEN的过期策略,TOKEN过期有固定的时间,过期策略指从何时开始计时,比如可以从登录开始计时,超过固定时间后过期;可以从最后请求时间开始计时,经过固定时间后过期
- 允许查询 是对某些业务需求,用户设置允许查询时才可以检索到,预留字段
- 用户属性 是用户解决数据权限的关键,来源于数据字典,可根据业务定义具体的值,例如"财务"、"销售",详情在后续数据权限章节讨论
允许终端 、用户属性 等可能要存储多个值(有限)的情况,为存储方便可以采取逗号间隔的方式存储,查询中通过FIND_IN_SET(以MYSQL为例)的方式查询。
不同登录方式可以判断登录的终端,例如手机验证码方式是移动端,扫码方式是微信端,不同的终端登录验证可以采取不同的实现方式。
"终端" 的概念有时对于业务需求尤其有用,比如实践过程中业务系统有此需求:用户可以"授权码"登录,授权码是业务用户自行设定的密码,可给对应的助理使用,授权码只能看到自己的数据,无法看到委托(委托是数据权限的一种概念,后续章节讨论)的数据,授权码操作的数据在审计字段中(创建人、更新人)都有前缀*号,便于查看那些是授权码的操作,此时就可以用"终端"的方式进行处理。
用户功能

通过用户属性设计后,用户功能就是根据用户属性进行系统化处理。功能详细说明如下:
- 新增 新增一个用户,注意必填项,用户名检查唯一性,用户名保存后不允许修改
- 修改 修改用户信息,不包括修改密码信息
- 删除用户 删除后需要删除对应的关联信息,包括从组织关联中删除,从角色关联中删除等等
- 查询 根据条件查询用户,属性中允许查询设置为False的不允许查询
- 明细 根据ID查看信息,对于此接口的某些字段需脱敏处理
- 资源授权 对离散的权限类型,建立角色反而增加负担,此时可以直接对用户进行授权
- 重置密码 密码是加密的,管理端无法修改密码,只能重置密码,该功能会发送随机密码到用户的邮箱中
- 修改密码 此功能针对业务端,需要原始密码校验
- 激活 属于状态管理的一种 初始创建的用户状态为未激活(管理系统暂时不考虑开放注册),通过激活后发送初始密码到用户邮箱,同时状态变为启用状态。
- 停用 某些情况下需要停用用户账号,比如用户休假甚至辞职,停用后无法登录
- 启用 停用的状态恢复启用状态
现代系统中安全尤为重要,尤其是用户的数据,在返回用户的接口中对数据须脱敏(将敏感的数据隐藏或不可读)处理,其中的敏感信息包括邮箱 、手机号 、密码 、微信等信息
状态对于实体对象很普遍,尤其是业务相关的对象,可以借助状态流 来查看或分析业务逻辑,对此系统引入了状态流,通过状态流控制状态的转换及哪些状态允许删除、那些状态允许编辑,在进行流转过程中会根据状态流自行判断是否合法操作,此功能在后续章节详细讨论。
用户关联关系
在权限系统设计-功能设计章节中与用户关联的关系有用户组 、角色 、组织 、职位,对此我们做了一些约定,具体如下:
- 用户组 包括多个用户,用来对多个用户统一进行资源权限分配和数据权限分配
- 角色 关联用户进行资源权限分配
- 组织 用户所在的部门,允许同一用户在不同部门,但在登录时必须明确位于哪个部门
- 职位 用户拥有的职位 允许用户拥有多个职位,但在同一个组织只允许拥有一个职位
通过以上定义,尤其是需要满足允许同一用户在不同部门 的原则下,用户和组织是一个整体,在和角色、用户组、职位关联的关系中是一个不可分割的整体,具体关系如下:
以上图仅列出角色资源权限关系,数据权限关系将在后续数据权限章节详细讨论
为设计的简洁性,暂时不考虑角色的继承、互斥等因素,尤其是互斥,反而为系统带来复杂的配置。
职位在系统中很重要,职位与组织的关联关系 是数据权限的一个设置维度,例如本部门 、下属部门等数据权限范围的概念,将在后续数据权限章节详细讨论。
总结
通过以上讨论完成了用户的属性设计和功能设计以及设计过程中需要注意的细节,下一章将开始用户组织的设计