本文原文由作者Amazing10原创发布于公众号业余码农,收录时有改动,感谢原作者的技术分享。
1、引言
某天中午,吃完午饭,摊在自己的躺椅上,想趁吃饱喝足的午后时间静静享受独自的静谧。
干点什么好呢?于是单手操作鼠标打开了一个陌生而隐秘的网站。正开着某个视频起劲。。。
突然浏览器弹出了一个提示:
请使用微信扫码登录账号,继续观看
这...
但是由于强烈的好奇驱使,迫于无奈,只好选择登录再继续观看。于是熟练的掏出手机,打开微信扫一扫对准上面的二维码,只听见 “叮” 的一声,网页上的二维码放佛活过来了,直接刷新出了本尊的微信头像,同时手机上也弹出登录的提醒。
心中略微惊叹,但没来得及多想。忙点击手机界面中登录按钮。此时网页刷新,恢复了正常,表示可以继续观看。
上网冲浪的时间总是过得很快,很快就有些疲倦。于是闭上眼睛,脑海中却浮现出了刚刚微信扫描二维码,然后登录网页的场景,心中再次惊叹,并开始思考起其中的原理来。。。
言归正传,本文将以轻松活泼的语言形式,为你分析和讲解微信手机扫码登录的技术原理,希望在你的IM中开发此功能时有所启发。
推荐阅读:另一篇同类文章《IM的扫码登录功能如何实现?一文搞懂主流的扫码登录技术原理》也值得一读。
学习交流:
- 即时通讯/推送技术开发交流5群:215477170[推荐]
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
(本文同步发布于:http://www.52im.net/thread-2941-1-1.html)
2、IM开发干货系列文章
本文是系列文章中的第23篇,总目录如下:
《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》
《IM消息送达保证机制实现(二):保证离线消息的可靠投递》
《如何保证IM实时消息的“时序性”与“一致性”?》
《IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?》
《IM群聊消息如此复杂,如何保证不丢不重?》
《一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)》
《移动端IM登录时拉取数据如何作到省流量?》
《通俗易懂:基于集群的移动端IM接入层负载均衡方案分享》
《浅谈移动端IM的多点登录和消息漫游原理》
《IM开发基础知识补课(一):正确理解前置HTTP SSO单点登录接口的原理》
《IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?》
《IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议》
《IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token》
《IM群聊消息的已读回执功能该怎么实现?》
《IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?》
《IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列》
《一个低成本确保IM消息时序的方法探讨》
《IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!》
《IM里“附近的人”功能实现原理是什么?如何高效率地实现它?》
《IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路》
《IM开发基础知识补课(八):史上最通俗,彻底搞懂字符乱码问题的本质》
《IM的扫码登功能如何实现?一文搞懂主流应用的扫码登录技术原理》
《IM要做手机扫码登陆?先看看微信的扫码登录功能技术原理》(本文)
3、原理解析
微信扫码登录现在在日常生活中已经是常见不能再常见的场景之一了,但是要知道微信首次公开这项功能时,却是惊艳众人。移动端与PC端以这样一种巧妙的方式链接在了一起,的确是让人惊叹。
以下是一个典型的微信扫码登录全过程:
本来想在Web版微信上截图,但扫码登陆后出现了下面的提示(貌似很多人都碰到过):
好吧,这很微信,反正就是不想让你好好用,用户爱咋咋滴。。。
如上图所示,操作过程如下:
1)第一步:电脑上打开PC端(出现2维码);
2)第二步:拿出手机,扫码2维码;
3)第三步:PC端显示扫码成功;
4)第四步:手机端“确认”登录;
5)第五步:成功登陆PC端。
上述实际操作过程,用户体验相当顺滑,也难怪刚出来那会,能惊艳到很多人。
那么,对于上述操作过程的技术实现原理是什么样的呢?
想起来之前听过的前后端的概念,知道账户的数据信息一般都是放在服务器上,前端负责向后端 “讨要数据” 并显示,后端则是对前端的 “讨要” 做出反应。
这样一来,猜测微信登录的过程可能就是:
1)网页前端向微信后台请求账号数据;
2)微信后台接受网页前端的请求,然后将他的账号数据返回;
3)网页前端接收到了数据后,在浏览器里进行显示。
于是,手脚麻利的画了个示意图:
当我正准备沾沾自喜的时候,突然看到桌面上的手机。咦,如果就只是这么个过程,那手机的作用是啥。于是才开始意识到,问题没这么简单。
好吧,我们城要再深入一点探秘微信扫码登录的过程。
4、过程分析
为了更深入的分析整个过程,我们可以去看看微信网页版,地址是:https://wx.qq.com/。
笔者看着网页中硕大的二维码陷入了沉思——这个二维码跟手机账号有没有什么对应关系呢?如果没有,那它又是怎么生成的呢?
思考间,于是打开了浏览器的开发者工具。
在网络监控一览找到了这幅二维码,与之对应的链接是:
https://login.weixin.qq.com/qrcode/gaO8cOQweA==
如下图所示:
然后习惯性地,尝试多次刷新页面,发现二维码不断发生变化,链接也不断更改:
https://login.weixin.qq.com/qrcode/AencxgKNFQ==
https://login.weixin.qq.com/qrcode/YcD7f_DxvA==
https://login.weixin.qq.com/qrcode/QblN8lCn2g==
似乎发现了些东西:二维码不断变化,其对应的链接尾的代码也相应变化,并且是随机性的变化。
这也就是说,每一次页面刷新都会随机且唯一地生成一个二维码。这或许可以与手机登录的过程联系起来。
似乎开始明白了,于是再次拿起手机,熟练的使用微信扫描了此时的二维码。
“叮” 的一声,网页上的二维码顿时变成了我帅气的微信头像。这个时候,我才突然意识到,是扫码之后网页才与他的微信账号建立起了联系。
如下图所示:
也就是说:
1)没有扫码之前,页面上的二维码只是随机生成的且与用户无关的码;
2)而当用户扫码之后,二维码便与用户帐号绑定在了一起。
原来手机扫码的用处是这样!
此时注意到,手机微信上弹出了『微信登录确认』的提醒。这个时候谨慎地点击了下方的登录按钮。
如下图所示:
随着平滑的动画一闪而过,网页上已经显示出了我的微信账号信息,显示微信账号已经登录。再一次体验这个过程,心中开始思索手机微信在登录过程中所起到的具体作用。
首先需要明白几个过程:
1)进入网页登陆界面,随机生成一个二维码;
2)通过手机扫描二维码,将微信账号与二维码绑定;
3)在手机微信点击登录按钮,授权网页登录微信账号;
4)网页获得的账号信息,将数据显示。
5、原理解释
回顾上述过程,结合最开始的原理猜测,开始思索整个环节,是哪里理解的不对。。。
1)网页的二维码到底从何而来?
2)是谁向微信后台请求了账号数据?
实际上:不同的网站可能都需要通过微信后台进行数据的获取,那么每一个网站必然也存在它的后台来给微信后台发送请求。
这样一来,整个过程就能解释得通了:
1)网站页面刷新,网页后台向微信后台请求授权登录;
2)微信后台返回登录所需二维码;
3)用户通过手机扫描二维码,并在手机上授权登录后,微信后台告知网页后台已授权;
4)网页后台向微信后台请求微信账号数据;
5)微信后台返回账号数据;
6)网页后台接收数据并通过浏览器显示;
6、技术剖析
正如上节所述,想清楚了整个过程后,我们应该对整个过程的技术实现进行进一步的探究。
在微信开发官方文档中,我找到了第三方网站应用微信登录开发指南:
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
我将整个过程梳理了一遍,画出了这个图:
如上图所示,整个技术实现如下。
(1)二维码的获得:
- 1)用户打开网站后,网站后台根据微信OAuth2.0协议向微信开发平台请求授权登录,并传递事先在微信开发平台中审核通过的AppID和AppSecrect等参数;
- 2)微信开发平台对AppID等参数进行验证,并向网站后台返回二维码;
- 3)网站后台将二维码传送至网站前端进行显示。
(2)微信客户端授权登录:
- 1)用户使用微信客户端扫描二维码并授权登录;
- 2)微信客户端将二维码特定的uid与微信账号绑定,传送至微信开发平台;
- 3)微信开发平台验证绑定数据,调用网站后台的回调接口,发送授权临时票据code;
(3)网站后台请求数据:
- 1)网站后台接收到code,表明微信开发平台同意数据请求;
- 2)网站后台根据code参数,再加上AppID和AppSecret请求微信开发平台换取access_token;
- 3)微信开发平台验证参数,并返回access_token;
- 4)网站后台收到access_token后即可进行参数分析获得用户账号数据。
在上述过程中,有几个参数值得解释一下(来源官方文档):
- 1)AppID:应用唯一标识,在微信开放平台提交应用审核通过后获得;
- 2)AppSecret:应用密钥,在微信开放平台提交应用审核通过后获得;
- 3)code:授权临时票据,第三方通过code进行获取access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。code的临时性和一次性保障了微信授权登录的安全性。
整个过程从网站后台向微信开发平台请求授权登录开始,最终目的是为了获得access_token:
access_token:用户授权第三方应用发起接口调用的凭证
在获得了access_token后就可以解析用户的一些基本信息,包括头像、用户名、性别、城市等。这样一来,整个微信扫描登录的过程就完成了。
7、写在最后
研究到这,终于大体上对微信扫码登录的整个过程有了清晰的认知。看起来似乎也不难,开发者只需要在网页后端做好对微信公众平台的接口调用即可实现扫码登录。
伸了伸懒腰,忽然又想到在整个过程中还需要考虑超时的问题。比如二维码超时未扫描、二维码扫描后超时授权、获得access_token后超时等等问题。
我发现一个简单的功能实现起来还是需要考虑许多细节,真的是纸上得来终觉浅呀。于是我下定决心,下次得少上网冲浪了,花点时间搭个服务器先把微信扫码登录过程实现看看。
不过,还得先去在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret才行。
想了想,还是让我先趟一会儿吧。。。
附录:更多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-2941-1-1.html)