重庆小潘seo博客

当前位置:首页 > 重庆网络营销 > 小潘杂谈 >

小潘杂谈

详解二维码登录的原理

时间:2020-09-13 21:30:07 作者:重庆seo小潘 来源:
这篇文章主要大家详细解析了微信QQ的二维码登录原理js代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 在很多地方就是都出现了使用二维码登录,二维码付款,二维码账户等应用(这里的二维码种马,诈骗就不说了),二维码验证,多终端辅助授权应用开始

这篇文章主要大家详细解析了微信QQ的二维码登录原理js代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在很多地方就是都出现了使用二维码登录,二维码付款,二维码账户等应用(这里的二维码种马,诈骗就不说了),二维码验证,多终端辅助授权应用开始多起来,这里先说下啥是二维码,其实二维码就是存了二进制数据的黑白图片,当出现要求二维码登录的时候,服务器会生成一条临时的唯一的二维码信息,发送到客户端以二维码(图片)的形式写入到网页,然后你就会看到统一的四个方形的二维码,如果做的好这个二维码信息应该是有时效的,这里暂且不考虑这些,就简单的微信登录作为例子看看吧:

详解二维码登录的原理

首先说下整个授权流程:

详解二维码登录的原理

在客户端网页中会不断向服务器发送https连接,并且这里传输很少的数据之后就断开连接了,下面看下微信网页中这个login1c709c.js文件:(function($, _aoWin) { _aoWin.QRLogin = {}; _aoWin.LoginLog = ""; var _sBaseHost = "", _oLoginQrCodeImg = document.getElementById("loginQrCode"); if (document.domain == "qq.com") { _sBaseHost = "weixin.qq.com"; } else if(location.hostname.match(/(wechat.com)$/)){ _sBaseHost = "wechat.com"; }else{ _sBaseHost = "wechatapp.com"; } var show_tip = 1, _sCurUUId, _oResetTimeout, _aWebMMCallbacks = [], _oDetactWebMMInterval = setInterval(function(){if(_aoWin.WebMM){clearInterval(_oDetactWebMMInterval);var callback;while(callback = _aWebMMCallbacks.shift()){if(typeof(callback) != "function") continue;callback();}} }, 1000); function _logInPage(_asLog){ _aoWin.LoginLog = LoginLog + _asLog + "n"; } function _afterLoadWebMMDo(callback){ if(!_aoWin.WebMM){_aWebMMCallbacks.push(callback); }else{callback(); } } function _reportNow(text){ _logInPage(text); _afterLoadWebMMDo(function(){WebMM.ossLog({Text: text});WebMM.flushOssLog(); }); } var reLoadQRImgCount = 0, loadQRCodeTime = 0, loadQRImgSucc = function(){clearInterval(loadQRImgWatchDog);_logInPage("Load QRCode Success, time=" + (new Date().getTime() - loadQRCodeTime) + "ms, reload count: " + reLoadQRImgCount); }, loadQRImgFail = function(img){_reportNow("Load QRcode fail!" + status + ", src: " + img.src + ", time: " + (new Date().getTime() - loadQRCodeTime) + "ms"); }, loadQRImgWatchDog = null; function _loadQRImg(uuid) { _poll(uuid); _logInPage("Load QRCode Start"); loadQRCodeTime = new Date().getTime(); _oLoginQrCodeImg.onload = function(){loadQRImgSucc();_oLoginQrCodeImg.onload = null; }; _oLoginQrCodeImg.onerror = function(){loadQRImgFail(this)}; _oLoginQrCodeImg.src = "https://login."+_sBaseHost+"/qrcode/"+uuid+"?t=webwx"; loadQRImgWatchDog = setInterval(function(){if (reLoadQRImgCount >= 5) {_reset();return;}reLoadQRImgCount++;var _img = new Image();_img.onload = function () {if(!_oLoginQrCodeImg.onload) return;_oLoginQrCodeImg.onload = null;_oLoginQrCodeImg.src = this.src;//replaceloadQRImgSucc();};_img.onerror = function(){loadQRImgFail(this)};_img.src = _oLoginQrCodeImg.src + "&r=" + new Date().getTime(); }, 5000); } var _sSecondRequestTime = 0, _nAjaxTimeout = 100 * 1000, _nNewLoginFuncErrCount = 0; function _poll(_asUUID) { var _self = arguments.callee,_nTime = 0; _sCurUUId = _asUUID; _logInPage("_poll Request Start, time: " + new Date().getTime()); _nTime = new Date().getTime(); $.ajax({ type: "GET", url: "https://login." + _sBaseHost + "/cgi-bin/mmwebwx-bin/login?uuid=" + _asUUID + "&tip=" + show_tip, dataType: "script", cache: false, timeout: _nAjaxTimeout, success: function(data, textStatus, jqXHR) {_logInPage("_poll Request Success, code: " + window.code + ", time: " + (new Date().getTime() - _nTime) + "ms"); switch (_aoWin.code) { case 200:_sSecondRequestTime = new Date().getTime() - _sSecondRequestTime;_logInPage("Second Request Success, time: " + _sSecondRequestTime + "ms"); clearTimeout(_oResetTimeout);var _fNewLoginFunc = function(){$.ajax({url: _aoWin.redirect_uri + "&fun=new",//new login pagetype: "GET",success:function(msg) {_logInPage("new func reponse, reponseMsg: " + msg);var code = msg.match(/<script>(.*)</script>/);var skey=msg.match(/<skey>(.*)</skey>/);if(code){eval(code[1]);}else{$("#container").show();$("#login_container").hide();}if(skey && skey[1]){WebMM.model("account").setSkey(skey[1]);}},error:function(jqXHR, textStatus, errorThrown){_nNewLoginFuncErrCount++;if(_nNewLoginFuncErrCount > 5){if(confirm("Call new login page func error, refresh?")){location.reload()}return;}_reportNow(_aoWin.redirect_uri + " New login page func error: " + textStatus +" retryCount:" + _nNewLoginFuncErrCount);setTimeout(_fNewLoginFunc, 500);}});};_fNewLoginFunc();_reportNow("/cgi-bin/mmwebwx-bin/login, Second Request Success, uuid: " + _asUUID + ", time: " + _sSecondRequestTime + "ms"); break; case 201:clearTimeout(_oResetTimeout); show_tip = 0; $('.errorMsg').hide(); $('.normlDesc').hide(); $('.successMsg').show();_reportNow("/cgi-bin/mmwebwx-bin/login, First Request Success, uuid: " + _asUUID);_reportNow("/cgi-bin/mmwebwx-bin/login, Second Request Start, uuid: " + _asUUID);_sSecondRequestTime = new Date().getTime();//_nAjaxTimeout = 5 * 1000;_self(_asUUID);break; case 408: setTimeout(function(){ _self(_asUUID); }, 500); break; case 400: case 500:_reset();_afterLoadWebMMDo(function(){ _aoWin.Log.d("500, Login Poll Svr Exception"); }); break; } }, error: function(jqXHR, textStatus, errorThrown) { if (textStatus == 'timeout') {setTimeout(function(){_self(_asUUID);}, 500); } else {setTimeout(function(){_self(_asUUID);}, 5000);_logInPage("_poll Request Error:" + textStatus);_afterLoadWebMMDo(function(){_aoWin.Log.e("Login Poll Error:" + textStatus);}); } } }); } var getUUIDCount = 0, _getUUIDWatchDog, _bGetUUIDSuccess = false;//ajax success