扫码登录,其实相当于一种授权机制。
二维码登录是一个涉及三方的交互过程:web 浏览器、移动端,服务后台。
基本交互流程如下:
a)web 浏览器:负责二维码的展示及移动端授权后的登录态展示。
b)移动端:负责扫码及授权。
c)服务后台:贯穿整个交互过程。
想要扫码登录,首先必须得有码。
二维码是一种特殊的数据载体,作为登录二维码,他首先必须具备一定的特性:
首先有一个前提需要明确的是:每一个二维码都必须是惟一的。或者严格一点说,当前存续期间的每一个二维码都必须是惟一的。
唯一,就要求二维码承载的数据必须有一部分能给它提供区分标识。
那怎么生成这样一个唯一标识呢?
方法,机制可能会很多,在这里我们只就其中一种做简要介绍:基于分布式缓存+随机数的生成机制
a)随机
随机数可以提供一定程度上的区分度,这依赖于随机数的生成原理,不同生成算法所生成的随机数区分度差别会很大。
这里我们选取 UUID 方式来提供基础的随机数生成。鉴于 UUID 的长度问题,我们可以去掉其中的连接符号。
b)分布式缓存
随机数可能重复,这可能是个必然的问题,所以我们进一步使用分布式缓存来保障标识的唯一性。
分布式缓存我们选取 redis 作为载体。基于键的的唯一性,我们通过将上一步骤生成的随机数写入分布式缓存,并添加特定次数重试机制来维护唯一标识数据。
登录二维码需要有限制的存续周期,这是提供安全性的基本保障。
登录鉴权是一个及其敏感的过程,数据的持续暴露通常会导致不可预知的安全性问题。存续周期通常选取在秒级别,不同的业务生态可以基于自身需求灵活调整。
我们可以把一个完整的访问链接(附带唯一标识及特定的参数)放入二维码,提供给移动端扫描。
这里需要注意的一点是,放入的数据量会直接影响生成的二维码图形的密集程度,过密的图形可能会带来不好的扫码体验。
二维码图形的生成有两种形式可以选择:服务端生成,web浏览器生成。
a)服务端生成:服务端直接生成二维码图形数据,web 浏览器只负责图形的展示,减少端上的业务复杂度。
b)web 浏览器生成:后台服务只负责提供二维码内部数据,图形的生成放到 web 浏览器方。这样做的好处是减少了数据传输的量,同时,考虑到服务端变更的成本问题,web 浏览器处理图形生成可以更灵活的定制不同样式的展示。
登录二维码是整个交互流程的核心,我们这里通过登录二维码的状态来标识不同的操作步骤。
a)待扫码
二维码生成完成后的状态。此时二维码处于待扫码状态。
b)已扫码
移动端扫码完成后,二维码需要更新为已扫码状态,web 浏览器获取到此状态,需要作相应的状态展示“已扫待确认”。
c)已确认
移动端扫码完成后,会有相应的提示“确认登录”操作,用户执行完“确认登录”后,二维码更新为已确认状态。
d)已登录
用户确认登录后,web 浏览器获取到“已确认”状态,可以进一步执行相应的登录态展示操作。同时将二维码状态更新为已登录,保证登录态的处理只执行一次。
e)已失效
失效产生的场景包括:移动端扫码完成后,如果用户执行取消操作(如果有),则可以执行相应的二维码数据删除操作(非必须),或者待登录二维码存续时间到期,二维码数据消失。
此时 web 浏览器查询到此状态则需要处理重新生成二维码的操作。二维码生成的触发,可以是引导用户主动操作刷新,或者 web 浏览器自动机制维持保持有效二维码展示。业务方可以基于用户体验和服务压力两方面权衡去抉择。
基于上述登录二维状态流转,web 浏览器需要在每一步都确保实时获悉登录二维码的状态。
可选的做法通常有轮训,websocket长链接等。
a)轮训
web 浏览器间断的向服务后台发送请求查询状态。每次查询,服务端可以快速返回(减少连接长时间占用),亦可以等待一段时间再返回(减少请求次数)。
b)websocket长链接
基于 websocket 长链接,后台服务可以实时推送登录二维码状态到前台。当然,这需要相应 web 技术支持。