扫码登陆业务流程
整体设计
-
服务设计
扫码登录本身涉及到的服务不多,我们重点关注的可能就是一个登陆模块的服务
另外会有一个网关服务,这个是任何业务都有的
除了服务本身,还会涉及到两个不同的需要区分开的设备端:PC端和手机端
PC端是需要登录的一方,手机端是已经登录的,要通过扫码帮助PC登陆的一方
-
存储设计
我们要存的是二维码信息,在扫码登录过程中,这个二维码是不断变化的, 最终确认之后
会生成一个 PC Token,一个设备的登录凭证就是一个Token,也就是一个设备一个Token
登录的时候就是用这个Token进行鉴权登录,这里我们看不到什么需要关系型查询的地方,应该用kv存储
流程分析
- PC端向登录服务申请二维码ID,从返回中拿到二维码ID
- 产生一个二维码ID,关联二维码ID和设备信息记录到Redis
- 生成和展示二维码
- 同个二维码ID在二维码服务生成二维码URL,PC端展示出二维码,PC端轮询二维码状态
- 移动端扫二维码,拿到二维码ID
- 移动端发起扫码请求,请求到达服务端,通过二维码ID拿到关联的设备信息,更新二维码状态,生成临时Token
- 确认登陆
- 使用临时Token确认登录,生成登录用的PC Token,把PC Token与二维码ID进行关联,更新二维码状态为已激活
要点分析
Redis信息存储
一开始申请二维码ID的时候,会生成一个二维码ID,关联PC设备信息,还会记录Status状态信息,此时是待扫码
随着扫码操作的进行,状态信息发生变化,Status -> 待确认
确认登录之后,状态信息发生改变,Status -> 已激活
所以整体来说Redis信息的存储内容是有三个阶段:生成时 -> 扫码时 -> 确认后
-
生成时Redis数据
key是二维码ID,value会复杂一点,我们抽象一下,主要就是两个数据
一个是DeviceInfo,即设备信息,设备ID等,我们可以看作一个整体
另一个是状态信息,,状态从生成 -> 待确认 -> 已激活 -> 关闭
public class DeviceInfo {
String deviceId; // 设备ID
String deviceType; // 登录设备类型,iphone、mac...
String position; // 登录地址
}
{
"qrIdxxx": {
"deviceInfo": {
"deviceId": "sdfsfaldfhfshlfhds",
"deviceType": "mac",
"position": "guangzhou"
},
"status": 1 //待扫码
}
}
-
扫码后Redis存储
扫码之后,在我们的电脑上可以看得到基本的用户信息,比如头像
这说明扫码的时候,是将账户信息传递过去了,很多实现里就是传递一个账户ID,PC拿到之后通过ID获取基本信息
这时候,Token的状态就会从待扫码变成待确认,整体内容变成这样:
{
"qrIdxxx": {
"accountId": "dsfsd1231321f",
"deviceInfo": {
"deviceId": "sdfsfaldfhfshlfhds",
"deviceType": "mac",
"position": "guangzhou"
},
"status": 2 //待确认
}
}
同时,在扫码之后,还会生成一个临时Token,临时Token关联手机端设备信息
{
"tmpToken...": {
"deviceInfo": {
"deviceId": "sdfsfaldfhfshlfhdz",
"deviceType": "iphone",
"position": "guangzhou"
},
}
}
-
确认后Redis存储
最后确认之后,Token对应的变为已激活
此时tmpToken也会被删除
{
"qrIdxxx": {
"accountId": "dsfsd1231321f",
"deviceInfo": {
"deviceId": "sdfsfaldfhfshlfhds",
"deviceType": "mac",
"position": "guangzhou"
},
"status": 3 //已激活
"pcToken": "xxxxxx"
}
}
安全性考虑
-
设备关联设计
这里有个细节设计,就是Token是有关联设备信息的
为什么要这样设计呢?目的是在于希望一个Token只能适用于一个设备
这样就算是Token泄露了,只要坏人不知道你的设备信息,依然无法登录,多一层保障
所以在后面登录的时候,会传递设备信息用来进行安全校验
-
临时Token设计
为什么需要临时Token的设计呢?对应到这个操作流程就是,为什么会有个确认登录的流程
直接扫码不就可以了吗?这里最主要还是产品的考虑,确认流程是必要的
你不小心扫了一下,就直接登录了,这多危险,很多厂家还加上几秒时间让你看清楚设备信息、地址等才能确认
正是因为有确认登录的这个逻辑,所以才需要临时Token,这样我们才能将确认和扫码关联起来
请求中携带了临时Token,只在扫码的时候返回给了手机端,通过这个凭证,可以一定程度上证明扫码的是你,确认的还是你
-
过期时间设计