携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情 >>
一、简介
从登录的交互形式角度,登录有很多方式:账号密码登录、验证码登录、手机号一键登录、扫码登录等等。
今天我们聊一聊扫码登录的原理。
先来看两个扫码登录的场景:
1. 手机已经登录知乎,如果我们想在PC网页登录,可以使用知乎移动端扫码登录。
2. 使用微信扫码登录PC网页ProcessOn(这是一个免费作图的网站)。**
从账号体系角度,这是扫码登录的两种方式:自有账户登录登录和第三方登录。
我们在面试中问“请讲一讲扫码登录的原理”,通常指的是自有账户登录;而在实际业务开发中,基于微信的第三方登录是很常见的一个需求。
下面我们讨论这两种扫码登录如何实现。
二、自有账户扫码登录
**前置条件:**用户手机已经登录账号(如知乎),因此有完备的用户信息。
整个登录过程中,一个关键的、串联整个过程的参数是“key”(或者叫场景id),后端、PC、移动端都是通过这个key关联到相应的信息,从而串联起整个登录过程。
扫码登录过程:
- 用户访问登录页面,前端向后端请求登录的二维码和key,这个key用来索引用户登录状态。
- 服务端生成二维码,并将key(假设是"123")保存(本地或redis),然后将二维码和参数返给前端,这里可以后端生成二维码并上传到OSS,然后返回给前端二维码的地址;也可以直接返回给前端字符串,前端自己去生成二维码:www.npmjs.com/package/qrc…。
- 前端获取到key="123"和二维码后,就使用key开始轮询登录状态,等待用户扫码登录。(这里的轮询可以用websocket长连接代替)。
- 用户手机已经扫码后,移动端跳转到授权登录页(携带参数key="123")。
- 用户点击登录后,前端调用后端接口,通知后端:“"123"对应的用户是我,我已经授权PC网页登录了,我的用户信息是:XXXXX”。
- 后端找到"123"对应的信息,更新用户登录状态为true,并更新用户信息。前端轮询再发轮询时候,后端发现状态改变,则返回给前端登录成功,并返回登录的用户信息。
- 前端收到登录成功的返回,就更新登录状态,展示用户信息,停止轮询。
注意:
这里的授权登录页只是实现移动端和服务端通信的一种方式,也可以用其他方式实现通信:二维码中只包含key信息,移动客户端扫码后解析出key值,然后通过一个写死的地址来和服务端通信,这样灵活性稍差;或者二维码中包含key信息和服务端接口名,移动端扫码后通过这个接口来和服务端通信。
三、第三方扫码登录
1. 微信第三方登录介绍
以微信扫码登录为例。
很多业务方使用微信登录,利用微信账户体系快速搭建自己的用户体系。
微信支持网页授权(官方开发文档)、开放平台扫码登录(官方开发文档)、公众平台扫码登录(涉及的主要接口有:获取access_token、生成带参二维码、接收扫码事件)。
我们今天讨论公众平台扫码登录,下文的微信扫码登录特指公众号扫码登录。
2. 微信公众号扫码登录
微信扫码登录和基本的扫码登录的原理基本类似,但是由于手机登录的是微信,而PC登录的是业务方,属于第三方登录,需要微信服务器和业务服务器通信,因此多了一些交互过程。
从业务角度,最大的区别是,使用微信账号登录,而不是业务方自己的账号登录。
从系统结构角度,最大的区别是,生成二维码和登录过程都是微信服务器完成,业务服务器从微信服务器获取到二维码、业务服务器从微信服务器接收到登录(扫码)的事件;另外,微信扫码登录时候,业务的用户体系是通过微信的用户信息建立的,因此还需要登录注册过程(登录注册过程,即,如果发现用户已经注册过,则返回登录成功,并返回用户信息,如果发现用户未注册过,则将用户信息保存(相当于注册操作),然后返回给用户登录成功 + 用户信息。简单描述为:已注册 ? 登录 : 注册 + 登录
)。
和自有扫码登录类似,微信扫码登录前提是用户已经在手机端登录了微信。
另外业务服务器需要进行一系列的配置,才能和微信服务器进行通信。下面说明业务服务器需要进行哪些配置。
接入微信扫码登录的准备工作
接入微信主要就是要让业务服务器可以和微信服务器能够正常通信,但是微信服务器并不是随便可以通信的,需要进行配置,这样微信服务器才能认为和你的业务服务器通信是安全合法的。
通信主要有两个方面:一个是业务服务器请求微信服务器,另一个是微信服务器向业务服务器发送事件。
前者需要配置ip白名单,只有在白名单中的机器才会被微信服务器接收,否则都被认为是非法请求而拒绝。后者需要配置你的服务器地址,并进行验证,这样当有和你的公众号相关的事件发生,就会通过这个配置的服务器地址进行推送。
更具体地,需要做的准备工作有:
- 权限:认证的服务号,订阅号和未认证的服务号都没有获取带参二维码接口的权限,因此无法实现扫码登录。
- 开通微信公众号开发者(在微信公众号后台的基本配置中开启)
- 配置公众号服务地址并验证(在微信公众号后台的基本配置中配置并验证),这个地址也是后面接收扫码事件的。
- 配置公众号的ip白名单(serverless实例运行时候ip不固定,可以通过代理方式保证固定ip(例如阿里云文档给出的解决方案:help.aliyun.com/document_de…),也可以把微信后端接口放在云服务器上)。
- 实现access_token刷新模块,调用微信的任何接口都需要access_token:获取access_token。
微信扫码登录和自有账户扫码登录的区别
最关键的区别有两点:
- 业务服务器不是自己生成二维码,而是从微信服务器中获取带参二维码,然后给前端。
- 由于使用微信客户端扫码,业务服务器没法直接接收移动端的扫码事件,而是接收微信服务器发来的扫码事件。
简单地说,微信扫码登录过程的二维码生成和扫码都是在微信服务器,业务服务器只是做个中转工作,并记录事件信息用来进行登录。
微信公众号扫码登录步骤
微信扫码登录过程:
- 用户访问登录页面,前端向后端请求登录的二维码和key,这个key用来索引用户登录状态。
- 业务服务器向微信请求带参二维码(生成带参二维码),这个参数是自定义的(假设是"123"),微信中称为“场景值”。注意请求时候需要带上access_token。
- 业务服务端收到二维码,和“场景值”key="123",保存场景值后,一起返回给前端。
- 前端获取到key="123"和二维码后,就使用key开始轮询登录状态,等待用户扫码登录
- 用户手机使用扫码后,移动端跳转到二维码对应的地址(形式是:weixin.qq.com/q/02qRGxU8s…
- 微信客户端解析地址后会和微信服务器通信,告知微信服务器:“这个场景值123,我已经授权登录”。
- 如果用户已经关注公众号,微信会推送一个扫码事件给业务服务器,如果用户未关注公众号,会跳转到公众号详情,用户点击关注后,推送关注后的用户扫码事件给业务服务器。扫码事件文档:接收扫码事件。
- 业务服务器收到事件时候,找到"123",根据用户信息走登录注册流程,然后更新用户登录状态为true,并更新用户信息。前端再发轮询时候,后端发现状态改变,则返回给前端登录成功,并返回登录的用户信息。
- 前端收到登录成功的返回,就更新登录状态,展示用户信息,停止轮询。
简而言之,业务服务器从微信服务器请求带参二维码,返回给PC网页,用户使用微信扫码后,如果用户已经关注过公众号,微信服务器会给业务服务器推送一个已关注的扫码事件,如果用户未关注公众号,扫码后会跳转到公众号详情页,用户点击关注后,微信服务器会给业务服务器推送一个关注后的用户扫码事件,这两种事件都会携带用户信息,业务服务器根据事件中的数据进行登录注册的业务逻辑。
四、总结
扫码登录实际上就是把移动端的登录状态同步到PC端,这个同步过程需要服务器进行校验和传递数据。扫码过程其实就是把PC的信息同步给移动端,从而能够让整个数据链路串联起来,如果PC展示一个url,移动端手动输入,也是可以实现的,但扫码的操作更便捷和安全。