扫码登录
扫码登录
什么是扫码登录?
现在扫码登录是一种很常见的登录方式。当用户需要登录某个网站时,网站会提供一种扫码登录的方式,用户打开相应的手机 App,扫描网站上显示的二维码,然后在 App 中确认登录,网站监测到用户确认登录后,跳转到登录成功页面。从这个形式上看,扫码登录就是将用户在手机 App 中的登录状态同步到网站中。
用一句话概括:扫码登录本质上是请求登录方请求已登录方将登录凭证写入特定媒介的过程。这里的请求登录方为 Web 端,已登录方为 APP 端,登录凭证可以是用户信息,也可以是换取用户信息的凭证,而特定媒介是某一张二维码。
扫码登录原理
具体的扫码登录流程如下:
 |
- 打开登录页面,展示一个二维码,同时轮询二维码状态 (web)
- 打开 APP 扫描该二维码后,APP 显示确认、取消按钮 (app)
- 登录页面展示被扫描的用户头像等信息 (web)
- 用户在 APP 上点击确认登录 (app)
- 登录页面从轮询二维码状态得知用户已确认登录,并获取到登录凭证 (web)
- 页面登录成功,并进入主应用程序页面 (web)
整个过程中,一张特定二维码起到了连接请求登录方和已登录方桥梁的作用。而二维码本质上就是通过某种约定的编码方式将一段文本信息转换为一个能够被解码识别的图片,其本质就是一段文本信息。所以,我们可以将二维码 ID、创建时间、过期时间等信息写入二维码,APP 终端通过解码二维码信息(这是终端媒介具备的基础功能),就能够识别出此二维码。
在 Web 端,一般会有一个请求生成二维码的接口,此接口会返回二维码 ID 和二维码连接,ID 用于查询二维码最新状态,链接用于展示。
这样,Web 端和 APP 端就建立起了一个共识:二维码 ID。APP 端通过授权修改二维码状态,Web 端能通过轮询监听到二维码状态变化,并获取到登录凭证,从而完成登录。
再来详细分解一下,二维码一共具有哪些状态:
- 未扫描
- 已扫描,等待用户确认
- 已扫描,用户同意授权
- 已扫描,用户取消授权
- 已过期
APP 可以修改二维码状态,一共会用到三个接口:
- 确认已扫描
- 同意授权
- 取消授权
一旦 Web 端监听到二维码状态变成了同意授权,登录就完成了。
APP 端请求这些接口时,需要带上登录凭证(这是显然的),后端接口能够从此判断同意授权的用户,从而将二维码 ID 和用户 ID 绑定起来。
Web 获取到扫码登录结果方式
轮询(现在大多数网站常用的方式)
前端通过定时发送请求去请求后端,返回数据根据返回的数据去修改扫码的状态。 后端写一个 controller,去 service 查询 传过来的 uid 的扫码状态,根据不同状态,返回不同的 data,如果已确认 登录 将带有 token 去跳转到主页面,登录成功。
轮询:客户端定时向服务器发送 Ajax 请求,服务器接到请求后马上返回响应信息并关闭连接。
优点:后端程序编写比较容易。
缺点:请求中有大半是无用,浪费带宽和服务器资源。
实例:适于小型应用。
http 轮询比 websocket 开发简单, 消耗更少的服务器资源
长轮询(后端轮询)
前端发送一个请求,后端采用异步的方式去处理,阻塞前端请求去轮询检查 uid 的状态,当 uid 发送变化或者过期的时候去返回响应状态,减轻后端响应多次请求的弊端,但后端需要轮询。
长轮询:客户端向服务器发送 Ajax 请求,服务器接到请求后 hold 住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
优点:在无消息的情况下不会频繁的请求,耗费资源小。
缺点:服务器 hold 连接会消耗资源,返回数据顺序无保证,难于管理维护。
实例:WebQQ、Hi 网页版、Facebook IM。
WebSocket
轮询与长轮询都是基于 HTTP 的,两者本身存在着缺陷:轮询需要更快的处理速度;长轮询则更要求处理并发的能力; 两者都是 “ 被动型服务器 “ 的体现: 服务器不会主动推送信息,而是在客户端发送 ajax 请求后进行返回的响应。而理想的模型是 “ 在服务器端数据有了变化后,可以主动推送给客户端 “,这种 “ 主动型 “ 服务器是解决这类问题的很好的方案。Web Sockets 就是这样的方案。