扫码登陆原理
以微信网页版为例,看一下二维码登陆的原理。
浏览器打开登陆页面
打开页面之后,前端脚本会完成下面几个过程:
(1)请求二维码
浏览器打开页面之后,会首先向服务器发送一个请求,获得二维码,
[外链图片转存中…(img-o9zYaSOy-1577966200637)]
利用解析二维码工具可以得到二维码的内容https://login.weixin.qq.com/l/Ie00Yc04-A==
,可以看出来,实际上这个二维码包含的信息实际上就是这个请求的URL
这个URL后面对应的Ie00Yc04-A==
是一个全局唯一ID,它的用处就是用来识别请求登陆的客户端,如何识别后面会讲解
(2)通过轮询建立『长连接』
打开这个页面之后,浏览器会通过堵塞等待的轮询变相的建立了一个长连接,这个轮询是每间隔25秒向服务器发送一个请求<srcipt>
的GET请求:
[外链图片转存中…(img-0hTjiow9-1577966200639)]
如果25秒之内用户没有扫描这个二维码,这个请求会返回200
,结束它的使命。浏览器会再次发送一个请求。这个请求的地址是https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=Ie00Yc04-A==&tip=0&r=-1708735754&_=1577961552943
可以看到,通过这个请求里包含了一个uuid
字段,值就是前面提到的全局唯一ID,我们可以认为这个ID就是这个所谓的长连接的ID
查看了一下微信网页版的前端代码:
function checkLoginHandler(data) {
/**
* code:
* 200: 成功
* 201:扫描成功,但未点确认
* 408:未扫描
* 400:未知
* 500: login poll srv exception
*
*/
switch (data.code) {
case 200:
loginFactory.newLoginPage(data.redirect_uri).then(function(msg) {
var ret = msg.match(/<ret>(.*)<\/ret>/),
code = msg.match(/<script>(.*)<\/script>/),
skey = msg.match(/<skey>(.*)<\/skey>/),
wxsid = msg.match(/<wxsid>(.*)<\/wxsid>/),
wxuin = msg.match(/<wxuin>(.*)<\/wxuin>/),
passticket = msg.match(/<pass_ticket>(.*)<\/pass_ticket>/),