微信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;//replace
loadQRImgSucc();
};
_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 page
type: "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之后,你就会从网页客户端这边看到请求登录的一面,网页客户端每隔500毫秒就向服务器发起ssl请求,请求当前的二维码是否被其他客户端(手机)授权,如果返回结果是201,就是说明已经获取扫描二维码终端相同的账号登录授权,如果是其他情况就再隔500毫秒再循环发请求。这个过程会一直持续到二维码被扫描通过或者二维码超时(失效)为止。
其中使用的工具有: 抓包工具 Fidller ,Chrome F12开发人员工具,注意偶然的发现,微信的客户端有一个min-webmm1cba21.js ,其中清晰可见的XSS filter规范, 这对于那些喜欢白盒测试XSS的鸽子又有希望拿Q仔了!!!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多支持Myblog。
原文地址:http://www.jb51.net/article/87250.htm
具有一定的参考价值,感兴趣的小伙伴们可以参考一下
在很多地方就是都出现了使用二维码登录,二维码付款,二维码账户等应用(这里的二维码种马,诈骗就不说了),
二维码验证,多终端辅助授权应用开始多起来,这里先说下啥是二维码,其实二维码就是存了二进制数据的黑白图片,
当出现要求二维码登录的时候,服务器会生成一条临时的唯一的二维码信息,发送到客户端以二维码(图片)的形式写入到网页,
然后你就会看到统一的四个方形的二维码,如果做的好这个二维码信息应该是有时效的,这里暂且不考虑这些,
就简单的微信登录作为例子看看吧:

首先说下整个授权流程:

在客户端网页中会不断向服务器发送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;//replace
- loadQRImgSucc();
- };
- _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 page
- type: "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之后,你就会从网页客户端这边看到请求登录的一面,网页客户端每隔500毫秒就向服务器发起ssl请求,请求当前的二维码是否被其他客户端(手机)授权,如果返回结果是201,就是说明已经获取扫描二维码终端相同的账号登录授权,如果是其他情况就再隔500毫秒再循环发请求。这个过程会一直持续到二维码被扫描通过或者二维码超时(失效)为止。
其中使用的工具有: 抓包工具 Fidller ,Chrome F12开发人员工具,注意偶然的发现,微信的客户端有一个min-webmm1cba21.js ,其中清晰可见的XSS filter规范, 这对于那些喜欢白盒测试XSS的鸽子又有希望拿Q仔了!!!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多支持Myblog。
原文地址:http://www.jb51.net/article/87250.htm
微信QQ的二维码登录原理js代码解析的更多相关文章
- 微信QQ的二维码登录原理浅析
在非常多地方就是都出现了使用二维码登录,二维码付款,二维码账户等应用(这里的二维码种马,诈骗就不说了),二维码验证,多终端辅助授权应用開始多起来,这里先说下啥是二维码,事实上二维码就是存了二进制数据的 ...
- 二维码(2)二维码登录原理及Android客户端示例
1,原理 服务器: 数据库: 建立一个2维码登录的数据表,产生一个登录页时,插入一条记录X,X含将要登录的用户名字段(初始为空),2维码中的数据字段(唯一) 登录页面: 在产生的2维码中包含关键数据Y ...
- 用c#开发微信 (20) 微信登录网站 - 扫描二维码登录
像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 1 创建网站应用 在微信开放平台创建一个网站应用 https:// ...
- Asp.Net微信登录-电脑版扫描二维码登录
像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 一.创建网站应用 在微信开放平台创建一个网站应用 https:// ...
- C#微信登录-电脑版扫描二维码登录
像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 一.创建网站应用 在微信开放平台创建一个网站应用 https:// ...
- java 扫描微信公众号二维码,关注并登录逻辑
场景:户扫描微信公众号的二维码,关注后自动登录网站,若已关注则直接登录. 逻辑: 系统生成带参数的临时二维码:参数 scene_str 自定义为唯一值(可以是uuid),临时二维码的生成方式参照官方接 ...
- Java 扫描微信公众号二维码,关注并自动登录网站
https://blog.csdn.net/qq_42851002/article/details/81327770 场景:用户扫描微信公众号的二维码,关注后自动登录网站,若已关注则直接登录. 逻辑: ...
- node.js Websocket实现扫码二维码登录---GoEasy
最近在做一个扫码登录功能,为此我还在网上搜了一下关于微信的扫描登录的实现方式.当这个功能完成了后,我决定将整个实现思路整理出来,方便自己以后查看也方便其他有类似需求的程序猿些. 要实现扫码登录我们需要 ...
- C(++) Websocket实现扫码二维码登录---GoEasy
最近在做一个扫码登录功能,为此我还在网上搜了一下关于微信的扫描登录的实现方式.当这个功能完成了后,我决定将整个实现思路整理出来,方便自己以后查看也方便其他有类似需求的程序猿些. 要实现扫码登录我们需要 ...
随机推荐
- MVC之Ajax如影随行
一.Ajax的前世今生 我一直觉得google是一家牛逼的公司,为什么这样说呢?<舌尖上的中国>大家都看了,那些美食估计你是百看不厌,但是里边我觉得其实也有这样的一个哲学:关于食材,对于种 ...
- Spring Boot整合RabbitMQ详细教程
原文:https://blog.csdn.net/qq_38455201/article/details/80308771 1.首先我们简单了解一下消息中间件的应用场景 异步处理 场景说明:用户注册后 ...
- 视图Ext.Viewport和窗口Ext.Window用法
Viewport不需要再指定renderTo,而我们也看到Viewport确实填充了整个浏览器显示区域,并会随着浏览器显示区域大小的改变而改改.他有三个特点: 1).创建即可使用.不需要渲染,当组件在 ...
- 技术交流:DDD在企业开发的案例分享
背景 因为工作上的原因,这次技术交流准备的不够充分,晚上通宵写的演示代码,不过整个过程还是收获蛮大的,具体如下: 对原子操作有了更深入的了解,自己写的无锁循环队列(有点类似 RingBuffer)终于 ...
- Selenium2+python自动化47-判断弹出框存在(alert_is_present)
前言 系统弹窗这个是很常见的场景,有时候它不弹出来去操作的话,会抛异常.那么又不知道它啥时候会出来,那么久需要去判断弹窗是否弹出了. 本篇接着Selenium2+python自动化42-判断元素(ex ...
- Coursera课程《Python数据结构》中课程目录
Python Data Structures Python Data Structures is the second course in the specialization Python for ...
- [leetcode]Reorder List @ Python
原题地址:http://oj.leetcode.com/problems/reorder-list/ 题意: Given a singly linked list L: L0→L1→…→Ln-1→Ln ...
- Search for a Range leetcode java
题目: Given a sorted array of integers, find the starting and ending position of a given target value. ...
- 理解JavaScript里this关键字
1.全局代码中的this:始终指向window 2.函数代码中的this: }; var bar = { x: , test: function () { alert(this === bar); a ...
- quickcocos2dx framework环境变 fatal error C1083: 无法打开源文件:“.Box2D/Dynamics/b2World.h”: No such file or d
: fatal error C1083: 无法打开源文件:".Box2D/Dynamics/b2World.h": No such file or directory 解决方法 ...
