扫码登录
场景
在网页版qq邮箱,微信登录账号等时候,无需输入账号和密码,只需要在手机上扫码即可完成登录
登录分析
扫码登录涉及3种角色: PC端, 手机端, 服务端
涉及围绕这三端进行,每一端完成应该完成什么功能,应该怎么实现,端与端如何交互
两个问题
- 手机端如何认证
- pc端如何完成登录
普通登录流程:
PC端输入账号密码完成认证,然后服务器给PC同步返回token key标志, PC再次请求服务端,需要携带token key,用于标志和证明自己已登录
服务端响应时,对token key进行校验,通过则正常响应;校验不通过则失败; token过期则需要再次登录认证,获取新的token key
现在扫码登录:
- 不是通过账号密码,而是由手机端扫码完成
- PC端没法同步获取认证成功后的凭据, 必须用某种方法来让PC获取凭据
扫码登录实现
手机端如何完成认证
二维码如何生成
二维码可以存储任何字符串,扫码就是从图像中获取字符串包含的数据
生成流程
pc端请求服务端,服务端返回数据,PC端显示这些数据
数据包含什么
二维码是重要的媒介,服务端必须给这个数据生成唯一的标志作为二维码ID,同时设置过期时间。PC端根据二维码ID数据显示二维码
同时服务端应该保存二维码状态: 未扫描, 已成功, 已失效
APP认证机制
首先, APP不存储登录密码,只有第一次登录二维码基于账号密码,重启手机也不需要重新登录
设备id, device_id,每台设备都是惟一的,imei码
- APP登录除了账号密码,还有设备信息
- 账号密码校验通过,服务端会把账号和设备进行绑定,进行持久化保存,包含了账号ID,设备ID,设备类型等
- APP每次请求除了携带token key。还需要携带设备信息
因为移动端设备唯一性,可以为每个客户端生成专属token,token不需要过期,这就是可以一次登录,长久使用的原理
手机扫码做了什么
两件事:
- 扫码: 识别二维码,获取唯一二维码ID
- 确认登录: 手机端通过**带认证信息(token 设备信息)、二维码信息(二维码ID)**请求服务端,完成认证过程,确认PC端登录
PC端如何完成登录(重点)
手机端完成确认后,服务器就应该发送token给PC端完成登录
PC端如何获取token?
PC端可以通过获取二维码的状态来进行相应的响应:
- 二维码
未扫描
:无操作 - 二维码
已失效
:提示刷新二维码 - 二维码
已成功
:从服务端获取PC token
获取二维码状态有三种方式
轮询
PC端每隔一段时间主动给服务端发送一次二维码状态的查询请求
长轮询
长轮询是指客户端主动给服务端发送二维码状态的查询请求,服务端按情况对请求进行阻塞(hold住请求不关闭),直至二维码信息更新或者超时。当客户端接收到返回结果后,若二维码仍未被烧卖,则继续发送查询请求,直到状态改变(已失效或已成功)
websocket
Websocket是指在前端生成二维码后,会与后端建立连接,一旦后端发现二维码变化,直接通过建立的ws连接主动推送信息给前端
PS: 建议使用轮询,微信,淘宝登录都用轮询
短轮询简单无状态,支持水平扩容(加机器)实现高并发
维持大量websocket可能导致攻击,不适合扩容
长连接负载和消耗较大
总结:
整体流程如上图,以轮询为例:
- 访问PC端二维码生成页面,PC端请求服务端获取唯一二维码ID
- 服务端生成相应的二维码ID,设置二维码过期时间状态等
- PC获取二维码ID,生成相应二维码
- 手机端扫描二维码,获取二维码ID
- 手机端确认登录,将手机端token和二维码ID发送给服务端
- 服务端校验手机端token,根据手机端token和二维码ID生成PC端token
- PC端通过轮询方式请求服务器,通过二维码ID获取二维码状态,如果成功,返回 PC token, 登录成功
参考原文:https://juejin.cn/post/7021515145335554079