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

首先说下整个授权流程:

在client网页中会不断向server发送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ִfunction _getUUID() {getUUIDCount++;var _self = arguments.callee,_loadError = function(errorText){_reportNow("Load UUID Error! ErrorText: " + errorText + " getUUIDCount=" + getUUIDCount);if(getUUIDCount > 5){if (confirm("Load uuid error. Refresh?")) {location.reload();}}setTimeout(function(){_self();}, 500);};clearTimeout(_getUUIDWatchDog);_getUUIDWatchDog = setTimeout(function(){if(!_aoWin.QRLogin.code){_logInPage("GetUUID Timeout, WatchDog Run");_self();}}, 10000);$.ajax({type: "GET",url: "https://login." + _sBaseHost + "/jslogin?appid=wx782c26e4c19acffb&redirect_uri="+encodeURIComponent(location.protocol+"//"+location.host+"/cgi-bin/mmwebwx-bin/webwxnewloginpage")+"&fun=new&lang=" + document.lang,dataType: "script",cache: false,success : function(){clearTimeout(_getUUIDWatchDog);if(_bGetUUIDSuccess) return;if (_aoWin.QRLogin && _aoWin.QRLogin.code == 200) {_logInPage("GetUUID Success, UUID=" + QRLogin.uuid);_bGetUUIDSuccess = true;clearTimeout(_oResetTimeout);_oResetTimeout = setTimeout(function(){location.reload();//Note: Don't run _reset(). If you run _reset(), there will may have many _poll request, as they get 408 return code}, 5 * 60 *1000);//5 mins_loadQRImg(QRLogin.uuid);} else {var QRLoginCode = (_aoWin.QRLogin && _aoWin.QRLogin.code) ? _aoWin.QRLogin.code : "None";_logInPage("GetUUID Error, QRLogin.code=" + QRLoginCode);_loadError("QRLogin.code= "  + QRLoginCode);}},error : function(xhr, textStatus, errorThrown){_logInPage("GetUUID Error, textStatus=" + textStatus);_loadError(textStatus);}});}function _reset(){location.reload();}if ($("#login_container").is(":visible") ) {_getUUID();}var _bHadLog = false;function _ossLog() {if (_bHadLog) return;_bHadLog = true;var _sUvid = document.cookie.match(new RegExp( "(^| )"+"webwxuvid"+"=([^;]*)(;|$)"));if(!_sUvid || _sUvid.length < 3) return;_sUvid = _sUvid[2];(new Image()).src = "/cgi-bin/mmwebwx-bin/webwxstatreport?funkey=indexdemo&uvid="+_sUvid+"&uuid="+_sCurUUId;}if($("img.guide").length > 0) {var _nTimer = 0,_oGuide$ = $(".guide"),_oGuideTrigger$ = $("#guideTrigger, #tipTrigger"),_oMask$ = $(".mask");function _back() {_nTimer = setTimeout(function() {_oMask$.stop().animate({opacity:0}, function(){$(".mask").hide()});_oGuide$.stop().animate({marginLeft:"-120px",opacity:0}, "400", "swing",function(){_oGuide$.hide();});}, 100);}/*guide*/_oGuide$.css({"left":"50%", "opacity":0});_oGuideTrigger$.css({"backgroundColor":"white", "opacity":"0"});_oGuideTrigger$.mouseover(function(){clearTimeout(_nTimer);_oMask$.show().stop().animate({"opacity":0.2});_oGuide$.css("display", "block").stop().animate({marginLeft:"+168px", opacity:1}, 900, "swing", function() {_oGuide$.animate({marginLeft:"+153px"}, 300);});_ossLog();}).mouseout(_back);_oGuide$.mouseover(function(){clearTimeout(_nTimer);}).mouseout(_back);}
})(jQuery, window);

细读js之后,你就会从网页client这边看到请求登录的一面,网页client每隔500毫秒就向server发起ssl请求,请求当前的二维码是否被其它client(手机)授权,假设返回结果是201,就是说明已经获取扫描二维码终端同样的账号登录授权,假设是其它情况就再隔500毫秒再循环发请求。这个过程会一直持续到二维码被扫描通过或者二维码超时(失效)为止。

当中使用的工具有: 抓包工具 Fidller ,Chrome F12开发者工具,注意偶然的发现,微信的client有一个min-webmm1cba21.js ,当中清晰可见的XSS filter规范, 这对于那些喜欢白盒測试XSS的鸽子又有希望拿Q仔了!!!

微信QQ的二维码登录原理浅析相关推荐

  1. 微信QQ的二维码登录原理js代码解析

    这篇文章主要大家详细解析了微信QQ的二维码登录原理js代码, 具有一定的参考价值,感兴趣的小伙伴们可以参考一下 在很多地方就是都出现了使用二维码登录,二维码付款,二维码账户等应用(这里的二维码种马,诈 ...

  2. 图示扫描二维码登录原理

    想要了解手机端扫描二维码登录原理,首先我们要了解二维码和token认证机制两个内容,接下来我们将用图示的方法来直观感受这个面试时候的paper tiger. (第一次用visio画图,用熟练之后就感觉 ...

  3. 二维码登录原理及生成与解析

    一.前言 这几天在研究二维码的扫码登录.初来乍到,还有好多东西不懂.在网上看到有人写了一些通过QRCode或者Zxing实现二维码的生成和解码.一时兴起,决定自己亲手试一试.本人是通过QRCode实现 ...

  4. 电脑版和手机版QQ都要手机版QQ扫描二维码登录?

    是的,电脑版和手机版 QQ 都需要使用手机版 QQ 扫描二维码登录.这是因为扫描二维码登录是 QQ 的安全认证方式之一.

  5. QQ网页微信、QQ二维码登录原理分析(整理)

    QQ和微信的登录过程中,使用二维码登录,这里根据网上的一些资料简单总结: 二维码是包含二进制数据的黑白图片.当进行登录时,服务器生成一条二维码信息,发送给PC客户端.这时,手机终端(已经存在指定账号登 ...

  6. Android安卓开发集成微信第三方扫描二维码登录-超级无敌具详细

    Android安卓开发中集成微信二维码登录的步骤: 写在前面的: 该教程使用AS作为演示,使用ecplise请参照微信官方文档下载相应jar等所需参考文档和资源.在最后,我会附上这个Activity的 ...

  7. 形象理解二维码登录原理

    之前在极客时间看到一个介绍二维码登录的原理,这里写篇文章记录一下.二维码是我们日常生活中随处可见,支付扫码,登录扫码,添加好友扫码,或者查看某些内容也需要扫码.今天分享一下二维码背后的技术和逻辑,并且 ...

  8. 二维码登录原理+Web端即时通讯技术

    前言 上周在写项目过程中遇到需要实现二维码的登录功能,将这个过程细节记录下来 二维码的登录过程,主要难点在于用户扫码了浏览器展示的二维码,但是浏览器本身是无法知道的,需要服务端告知信息. 涉及到 we ...

  9. 二维码登录——原理区

    2019独角兽企业重金招聘Python工程师标准>>> 1.PC端的逻辑 用户点击二维码按钮,向后台发送创建二维码的ajax异步请求,后台生成二维码后以二进制数据流的形式返回给前台, ...

最新文章

  1. 优化JS加载时间过长的一种思路
  2. 从0到1走进 Kaggle
  3. html按钮控制播放暂停,外部按钮控制video视频的播放暂停
  4. 什么?在 VSCode 里也能用 Postman了?
  5. 微软发布PowerShell Core第一个版本:支持多平台开发
  6. 一键安装lnmp脚本(包括软件版本)
  7. iptable防火墙流程图
  8. kafka启动后闪退
  9. Ubuntu 第2章 基本命令和文件系统
  10. 如何免费下载百度文库,豆丁网等付费文章
  11. 十个最常用深度学习图像/视频数据标注工具
  12. soundpool android,android – 如何获取Soundpool的持续时间
  13. Python绘图模块 -- turtle
  14. 计算机怎么快速查找应用,win10系统如何快速查找应用?win10系统快速查找应用的方法...
  15. 幂函数衰减系数公式推导(最小二乘法求解一元线性回归方程系数)
  16. 经纬度转WGS84坐标
  17. “Failed to load response data“ django@xframe_options_exempt 网站不许 Firefox 显示被嵌入的网页
  18. 展望 2017年商业智能BI发展的趋势分析
  19. [概率论]图像里的“白噪声”——电视机搜不到台时雪花斑点的形成原因 (不信谣,不传谣,与宇宙微波背景辐射没有任何关系)
  20. dx.bat转换jar 包(java 1.8)出现 unsupported class file version 52.0 …while parsing

热门文章

  1. 服务器通过笔记本电脑联网
  2. 批量计算图片的均值与标准差
  3. 易点易动助力达达-京东到家打通全集团固定资产数字化管理全链条
  4. Altium Designer新手教程
  5. 吴恩达-目标检测讲解笔记
  6. python-matplotlib-箱线图为不同的箱体设置不同颜色
  7. 我的学习路径与方法之机器学习导入篇
  8. 实验四 SQL语言的数据更新和视图
  9. 【darknet-yolo系列】yolov3 训练模型操作流程(包含所有资源下载)
  10. Dell 笔记本电脑BIOS详细解读