用户中心规划和实现
应公司发展需要,现在需要实现单点登录,以保证多个系统之间的用户一致。
故,本文旨在开发一个用户中心,以提供登录、注册、用户信息存储功能。
需求
系统需求基本如下
- 用户注册
- 用户登录
- 用户信息获取
- 用户登出
- 系统间的切换不再需要登录
细节分析
登录
登录总体采用oauth2协议完成
用户信息
用户信息分成两块
- 基本用户信息
- 业务系统自有信息
第二点由业务系统自行维护,不作处理。
对于基本信息,应该由用户中心存储,业务系统需要使用时向用户中心申请,这样以便各个业务系统之间的信息一致
如果需要修改,也应该交由用户中心或者通知用户中心
登出
登出需要保证一处登出,所有系统一并登出。
在此,设计思路是当用户在某一个业务系统,或者直接在用户中心登出时,用户中心登出用户并且通过http发送消息给所有登录了的业务系统,业务系统再把用户从自己系统中登出。
注:该方案仅适用于业务系统在自己控制之下的情况
系统切换
当用户在访问应用A的过程中,需要去访问应用B,此时中间应该会经过用户中心。用户中心某种手段,例如cookie,识别到当前登录的用户,直接跳转到应用B。
一般情况下将用户中心将数据存入session,浏览器端使用cookie保存就可以了。
但是cookie和session是有时限的,如果用户在应用A停留时间超过了这个时限,那么在经过用户中心的时候就会判断成未登录。
所以问题就成了用户中心需要记住用户。
结合上面的业务系统每次访问都需要请求用户中心,可以得知用户正处于活动中,这一流程是服务器间的交互,不经过浏览器。
用户中心这边
首先,用户登录之后,生成一个随机字串和用户id绑定,即写入redis。
然后将这个字串写入cookie,并保证cookie存活期为会话
业务系统的每次访问,根据用户id去获取这个随机字串,不断延长其expire
用户第二次进入用户中心,
后台通过cookie里的随机字串,在redis中寻找是否存在一个用户id,如果存在,则直接认证通过
绑定关系为双向绑定,代表redis中需要存两个key
流程
登录授权

登出

实现
oauth2协议并不复杂,此处略去不表,仅对网上少有资料的细节进行原理阐述。
授权码
授权码的生成需要将使用范围限定为指定业务系统和指定用户,不能混用或共用,且有效期不宜过长。
本次我不打算在用户中心保存授权码,而是采用类似JWT的实现方案。
将信息以json形式存储,加上加密和签名,组成一个字符串交给业务系统
首先确定json格式,暂定需要以下内容
- 业务系统id
- 用户id
- 授权时间
以上字段保密性要求不高,不过还是可以加上加密。
确定生成流程如下
- 构建json数据
- 进行对称加密
- 将密文和业务系统的client_secret连接后进行签名
- 将密文和签名按照规则(自定义)拼装后再base64编码
最后得到的数据就是授权码,其中密文和签名的拼接规则自定义即可,只要保证后续解析时能够完整地把数据给拆分开就行。
token
token由于上述的登出功能限制,必须由用户中心进行保存。
除此之外,token就没有什么特别的处理了,随便生成一个UUID,和user绑定起来就行了。