这篇文章给大家聊聊关于QQ防红直连网站源码分享,以及qq防红直链对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。
本文引用了3位作者“精品唯居”、“Yangfan2016”、“MrYun”的部分文章内容,一并感谢。
1、引言
扫码登录这个功能,最早应该是微信的PC端开始搞,虽然有点反人类的功能(不扫码也没别的方式登录),但不得不说还是很酷的。
下面这张图,不管是IM开发者还是普通用户,应该很熟悉:
于是,搞IM产品的老板和产品经理们,从此又多了一个要抛给程序员们的需求——“为什么微信有扫一扫登录,而我们的没有?”。
好吧,每次只要是微信有的功能,IM程序员们想甩锅,难度就有点大了,必竟老板们都都会想当然认为,微信有的“我”的IM产品里也得有。
既然无法回避,那就只能老老实实搞懂技术原理,然后自已使劲撸吧。
本文将简要的介绍扫码登录功能的技术实现逻辑,并实际结合淘宝、微信的扫码登录功能,学习和研究大厂主流应用的技术实现思路。
学习交流:
-即时通讯/推送技术开发交流5群:215477170[推荐]
-移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
(本文同步发布于:http://www.52im.net/thread-2892-1-1.html)
2、IM开发干货系列文章
本文是系列文章中的第22篇,总目录如下:
《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》
《IM消息送达保证机制实现(二):保证离线消息的可靠投递》
《如何保证IM实时消息的“时序性”与“一致性”?》
《IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?》
《IM群聊消息如此复杂,如何保证不丢不重?》
《一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)》
《移动端IM登录时拉取数据如何作到省流量?》
《通俗易懂:基于集群的移动端IM接入层负载均衡方案分享》
《浅谈移动端IM的多点登陆和消息漫游原理》
《IM开发基础知识补课(一):正确理解前置HTTPSSO单点登陆接口的原理》
《IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?》
《IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议》
《IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token》
《IM群聊消息的已读回执功能该怎么实现?》
《IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?》
《IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列》
《一个低成本确保IM消息时序的方法探讨》
《IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!》
《IM里“附近的人”功能实现原理是什么?如何高效率地实现它?》
《IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路》
《IM开发基础知识补课(八):史上最通俗,彻底搞懂字符乱码问题的本质》
《IM的扫码登功能如何实现?一文搞懂主流应用的扫码登陆技术原理》(本文)
3、基本技术原理
3.1扫码登录功能到底是什么样的?
首先介绍下什么是扫码登录。现在大部分同学手机上都装有微信、qq和淘宝这一类的软件。而这些app都有他们相对应的网页端。为了让用户在使用他们的网页时登录更加方便和安全,使用手机扫一扫就可以登录的服务,就显的自然而然了。
几个主流大厂应用扫码登录时的界面效果如下:
有很多小伙伴可能会感到很神奇,网页上只是显示了个二维码,它怎么就知道是哪个手机扫到了二维码,并且进行登录的呢?而且,登录完成以后,还能直接把用户信息显示给用户,真的是很神奇啊。
3.2扫码登录功能的完整技术逻辑
1)网页端与服务器的配合逻辑:
接下来就是对于这个服务的详细实现。
首先用户打开网站的登录页面的时候,向浏览器的服务器发送获取登录二维码的请求。服务器收到请求后,随机生成一个uuid,将这个id作为key值存入redis服务器,同时设置一个过期时间,再过期后,用户登录二维码需要进行刷新重新获取。
同时,将这个key值和本公司的验证字符串合在一起,通过二维码生成接口,生成一个二维码的图片(二维码生成,网上有很多现成的接口和源码,这里不再介绍)。然后,将二维码图片和uuid一起返回给用户浏览器。
浏览器拿到二维码和uuid后,会每隔一秒向浏览器发送一次,登录是否成功的请求。请求中携带有uuid作为当前页面的标识符。这里有的同学就会奇怪了,服务器只存了个uuid在redis中作为key值,怎么会有用户的id信息呢?
这里确实会有用户的id信息,这个id信息是由手机服务器存入redis中的。具体请继续阅读“手机端与服务器的配合逻辑”。
2)手机端与服务器的配合逻辑:
话说,浏览器拿到二维码后,将二维码展示到网页上,并给用户一个提示:请掏出您的手机,打开扫一扫进行登录。
用户拿出手机扫描二维码,就可以得到一个验证信息和一个uuid(扫描二维码获取字符串的功能在网上同样有很多demo,这里就不详细介绍了)。
由于手机端已经进行过了登录,在访问手机端的服务器的时候,参数中都回携带一个用户的token,手机端服务器可以从中解析到用户的userId(这里从token中取值而不是手机端直接传userid是为了安全,直接传userid可能会被截获和修改,token是加密的,被修改的风险会小很多)。手机端将解析到的数据和用户token一起作为参数,向服务器发送验证登录请求(这里的服务器是手机服务器,手机端的服务器跟网页端服务器不是同一台服务器)。
服务器收到请求后,首先对比参数中的验证信息,确定是否为用户登录请求接口。如果是,返回一个确认信息给手机端。
手机端收到返回后,将登录确认框显示给用户(防止用户误操作,同时使登录更加人性化)。用户确认是进行的登录操作后,手机再次发送请求。服务器拿到uuId和userId后,将用户的userid作为value值存入redis中以uuid作为key的键值对中。
3)登录成功时的逻辑:
然后,浏览器再次发送请求的时候,浏览器端的服务器就可以得到一个用户Id,并调用登录的方法,声成一个浏览器端的token,再浏览器再次发送请求的时候,将用户信息返回给浏览器,登录成功。这里存储用户id而不是直接存储用户信息是因为,手机端的用户信息,不一定是和浏览器端的用户信息完全一致。
4)详细的技术原理总结如下图所示:
4、淘宝的扫码登录技术实现
本节我们以淘宝的扫码登录为例,来实际研究分析一下淘宝的扫码登录实现逻辑。
登录界面https://login.taobao.com/member/login.jhtml传回来的参数为:
然后请求(GET)报文是这样的:
1https://qrlogin.taobao.com/qrcodelogin/qrcodeLoginCheck.do?lgToken=2c3b4d53ef0513787bf4ce711ea5ba53&defaulturl=&_ksTS=1540106757739_2804&callback=jsonp2805
关键的就是lgToken,是网页的唯一ID,当打开了二维码登录的时候,网页在轮询(应该是长轮询longpolling)调用接口去请求服务器。
如果没有扫码,返回的为:
如果扫了的话则会返回:
{
&34;:&34;,
&34;:&34;,
&34;:true
}
长时间没有扫码的话,网页端会停止轮询,二维码失效!
当手机端确认登录后,接口返回的是:
{&34;:&34;,&34;:true,&34;:&34;}
表示登录成功,当然手机端与服务端在点击&34;之间的交互可能就是这样:网页端生成的lgToken去请求服务端,服务端记住了这个lgToken并认为登录了,当网页端再次轮询请求接口时,就返回真正的登录态Token,网页端此时就可以凭着这个Token来登录了。
详细的技术逻辑如下图所示:
5、微信的扫码登录技术实现
5.1技术原理流程图
微信的网页版访问地址是:https://wx.qq.com/,有兴趣也可以自行深入研究。
5.2实际的技术实现逻辑
1)获取唯一的uuid,以及包含uid信息的二维码:
//获取uuid
getUUID:function(){
vare=t.defer();
returnwindow.QRLogin={},
$.ajax({
url:i.API_jsLogin,
dataType:&34;
}).done(function(){
200==window.QRLogin.code?e.resolve(window.QRLogin.uuid):e.reject(window.QRLogin.code)
}).fail(function(){
e.reject()
}),
e.promise
}
2)浏览器轮询服务器,获取扫码状态:
//查看扫码状态
checkLogin:function(e,a){
varn=t.defer()
,a=a||0;
returnwindow.code=0,
window.checkLoginPromise=$.ajax({
url:i.API_login+&34;+e+&34;+a+&34;+~newDate,
dataType:&34;,
timeout:35e3
}).done(function(){
newRegExp(&34;+location.host+&34;);
if(window.redirect_uri&&window.redirect_uri.indexOf(&34;+location.host+&34;)<0)
returnvoid(location.href=window.redirect_uri);
vare={
code:window.code,
redirect_uri:window.redirect_uri,
userAvatar:window.userAvatar
};
n.resolve(e)
}).fail(function(){
n.reject()
}),
n.promise
}
3)根据服务器返回的扫码状态,进行相应的操作:
*408扫码超时:如果手机没有扫码或没有授权登录,服务器会阻塞约25s,然后返回状态码408->前端继续轮询
*400二维码失效:大约5分钟的时间内不扫码,二维码失效
*201已扫码:如果手机已经扫码,服务器立即返回状态码和用户的基本信息(window.code=201,window.code.userAvator=&34;),->前端继续轮询
*200已授权:如果手机点击了确认登录,服务器返回200及token->前端停止轮询,获取到token,重定向到目标页
具体的代码示例如下:
//根据服务器返回的扫码状态,进行相应的操作
functiono(c){
switch(c.code){
case200:
t.newLoginPage(c.redirect_uri).then(function(t){
varo=t.match(/<ret>(.*)<\\/ret>/)
,r=t.match(/<script>(.*)<\\/script>/)
,c=t.match(/<skey>(.*)<\\/skey>/)
,s=t.match(/<wxsid>(.*)<\\/wxsid>/)
,l=t.match(/<wxuin>(.*)<\\/wxuin>/)
,d=t.match(/<pass_ticket>(.*)<\\/pass_ticket>/)
,f=t.match(/<message>(.*)<\\/message>/)
,u=t.match(/<redirecturl>(.*)<\\/redirecturl>/);
returnu?void(window.location.href=u[1]):o&&&34;!=o[1]?(alert(f&&f[1]||&34;),
i.report(i.AUTH_FAIL_COUNT,1),
voidlocation.reload()):(e.$emit(&34;,{
Ret:o&&o[1],
SKey:c&&c[1],
Sid:s&&s[1],
Uin:l&&l[1],
Passticket:d&&d[1],
Code:r
}),
void(a.getCookie(&34;)||n.report(n.ReportType.cookieError,{
text:&34;,
cookie:document.cookie
})))
});
break;
case201:
e.isScan=!0,
n.report(n.ReportType.timing,{
timing:{
scan:Date.now()
}
}),
t.checkLogin(e.uuid).then(o,function(t){
!t&&window.checkLoginPromise&&(e.isBrokenNetwork=!0)
});
break;
case408:
t.checkLogin(e.uuid).then(o,function(t){
!t&&window.checkLoginPromise&&(e.isBrokenNetwork=!0)
});
break;
case400:
case500:
case0:
vars=a.getCookie(&34;)||0;
s<5?(s++,
a.setCookie(&34;,s,.5),
document.location.reload()):e.isNeedRefresh=!0;
break;
case202:
e.isScan=!1,
e.isAssociationLogin=!1,
a.setCookie(&34;,0,2),
window.checkLoginPromise&&(window.checkLoginPromise.abort(),
window.checkLoginPromise=null),
r()
}
e.code=c.code,
e.userAvatar=c.userAvatar,
a.log(&34;,c.code)
}
5.3小结
微信网页端扫码登录时,轮询的数据返回采用的是JSONP的形式,这是为了解决跨域问题。如对JSONP不了解的,可以阅读《详解Web端通信方式的演进:从Ajax、JSONP到SSE、Websocket》一文的“三、JSONP”这一节。
微信网页端扫码登录时,轮询采用了后台根据扫码情况阻塞前台请求,优化轮询及减少前端的无效轮询。这种技术,请详见《新手入门贴:史上最全Web端即时通讯技术原理详解》一文中的“解决方案3.2:长轮询(long-polling)”这一节,
6、本文小结
扫码登录这个功能,现在已经不只出现有IM应用里,各种带有移动端的线上网站也都有了这个功能,所以本文中介绍的技术原理并不局限于只用于实现IM应用中的扫码登录。
另外,为了方便抓取真实的数据进行分析研究,本文中的PC端案例分析是针对的是网页端,但实际上如果你的PC端是富客户端(也就是.exe、.dmg这样的安装版),原理也是一样的,而且还不需要考虑浏览器里的跨域问题等。
阅读本文时,可能涉及到传统的Web端即时通讯技术(为了扫码登录的实时性),比如长轮询等,如果您对这些技术还不太了解的话,可以系统学习一下即时通讯网整理的有关Web端即时通讯方面的资料。比如从这两篇文章开始:《新手入门贴:详解Web端即时通讯技术的原理》、《Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE》。
附录:更多IM开发相关文章
[1]IM开发热门文章:
《新手入门一篇就够:从零开发移动端IM》
《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
《移动端IM开发者必读(二):史上最全移动弱网络优化方法总结》
《从客户端的角度来谈谈移动端IM的消息可靠性和送达机制》
《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障》
《腾讯技术分享:社交网络图片的带宽压缩技术演进之路》
《小白必读:闲话HTTP短连接中的Session和Token》
《移动端IM开发需要面对的技术问题》
《开发IM是自己设计协议用字节流好还是字符流好?》
《请问有人知道语音留言聊天的主流实现方式吗?》
《通俗易懂:基于集群的移动端IM接入层负载均衡方案分享》
《微信对网络影响的技术试验及分析(论文全文)》
《即时通讯系统的原理、技术和应用(技术论文)》
《开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀》
《QQ音乐团队分享:Android中的图片压缩技术详解(上篇)》
《QQ音乐团队分享:Android中的图片压缩技术详解(下篇)》
《腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率》
《腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)》
《腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)》
《如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源》
《基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?》
《腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)》
《腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)》
《字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8》
《全面掌握移动端主流图片格式的特点、性能、调优等》
《子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践》
《微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)》
《自已开发IM有那么难吗?手把手教你自撸一个Andriod版简易IM(有源码)》
《融云技术分享:解密融云IM产品的聊天消息ID生成策略》
《适合新手:从零开发一个IM服务端(基于Netty,有完整源码)》
《拿起键盘就是干:跟我一起徒手开发一套分布式IM系统》
>>更多同类文章……
[2]有关WEB端即时通讯开发:
《新手入门贴:史上最全Web端即时通讯技术原理详解》
《Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE》
《SSE技术详解:一种全新的HTML5服务器推送事件技术》
《Comet技术详解:基于HTTP长连接的Web端实时通信技术》
《新手快速入门:WebSocket简明教程》
《WebSocket详解(一):初步认识WebSocket技术》
《WebSocket详解(二):技术原理、代码演示和应用案例》
《WebSocket详解(三):深入WebSocket通信协议细节》
《WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)》
《WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)》
《WebSocket详解(六):刨根问底WebSocket与Socket的关系》
《socket.io实现消息推送的一点实践及思路》
《LinkedIn的Web端即时通讯实践:实现单机几十万条长连接》
《Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践》
《Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)》
《开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器》
《使用WebSocket和SSE技术实现Web端消息推送》
《详解Web端通信方式的演进:从Ajax、JSONP到SSE、Websocket》
《MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty?》
《理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性》
《微信小程序中如何使用WebSocket实现长连接(含完整源码)》
《八问WebSocket协议:为你快速解答WebSocket热门疑问》
《快速了解Electron:新一代基于Web的跨平台桌面技术》
《一文读懂前端技术演进:盘点Web前端20年的技术变迁史》
《Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!》
>>更多同类文章……
(本文同步发布于:http://www.52im.net/thread-2892-1-1.html)
文章到此结束,如果本次分享的QQ防红直连网站源码分享和qq防红直链的问题解决了您的问题,那么我们由衷的感到高兴!
