Jack Jiang

我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
posts - 467, comments - 13, trackbacks - 0, articles - 0

本文引用了作者“大古同学”的“二维码扫码登录是什么原理”一文的主要内容,为了更好的理解和阅读,即时通讯网收录时有修订和改动,感谢原作者的分享。

1、引言

自从微信的PC端使用扫码登陆认证逻辑后,这种方式似乎在越来越多的IM中看到(虽然我个人认为这种登录方式很酷,但并不方便,尤其手机不大身边的时候)。

 
▲ 上图微信PC端的扫码登录界面

最近刚好看到一个二维码的技术原理讲解视频,正好借此机会将扫码登录的详细技术原理梳理并总结一下,方便自已回顾,也希望能帮助到想在IM里开发类似功能的同行们。

补充说明:本文所涉及的扫码登陆原理并不是仅仅针对IM系统,同样适用于IM之外的其它系统。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK

(本文同步发布于:http://www.52im.net/thread-3525-1-1.html

2、专题目录

3、二维码登录的本质

3.1 扫码登录安全吗?

在2维码扫码登录的过程中,大家可能会有疑问:这二维码安全吗?会不会泄漏我的个人信息?我的im系统敢不敢也搞一个扫码登录呢?

针对这些顾虑,我们需要了解一下二维码扫码登录背后的技术和逻辑本质。

3.2 扫码登录的技术本质

二维码扫码登录本质上也是一种登录认证方式。

既然是登录认证,要做的也就两件事情:

  • 1)告诉系统我是谁;
  • 2)向系统证明我是谁。

举个实际的例子来理解一下:

  • 比如账号密码登录:账号就是告诉系统我是谁, 密码就是向系统证明我是谁;
  • 比如手机验证码登录:手机号就是告诉系统我是谁,验证码就是向系统证明我是谁。

那么扫码登录是怎么做到这两件事情的呢?

以微作的扫码登录为例:手机端应用扫PC端二维码,手机端确认后,账号就在PC端登录成功了!这里,PC端登录的账号肯定与手机端是同一个账号。不可能手机端登录的是账号A,而扫码登录以后,PC端登录的是账号B。

所以,第一件事情——“告诉系统我是谁”,是比较清楚的!

PS:通过扫描二维码,把手机端的账号信息传递到PC端,至于具体是怎么传的,我们后面再说。

第二件事情:“向系统证明我是谁”。扫码登录过程中,用户并没有去输入密码,也没有输入验证码,或者其他什么码。那是怎么证明的呢?

有些同学会想到,是不是扫码过程中,把密码传到了PC端呢?

但这是不可能的。因为那样太不安全的,客户端也根本不会去存储密码。

我们仔细想一下,其实手机端APP它是已经登录过的,就是说手机端是已经通过登录认证。所说只要扫码确认是这个手机且是这个账号操作的,其实就能间接证明我谁。

4、认识二维码

那么如何做扫码登陆的确认呢?我们后面会详细说明,在这之前我们需要先认识一下二维码! 在认识二维码之前我们先看一下一维码!

▲ 这就是一维码

所谓一维码,也就是条形码,条形码实际上就是一串数字,以平时生活中的商品为例,它上面的一维码存储的就是商品的编号。

二维码其实与条形码类似,只不过它存储的不一定是数字,还可以是任何的字符串,你可以认为,它就是字符串的另外一种表现形式。

在搜索引擎中搜索二维码,你可以找到很多在线生成二维码的工具网站,这些网站可以提供字符串与二维码之间相互转换的功能,比如 草料二维码网站。

▲ 输入一段字符串就能生成二维码

在左边的输入框就可以输入你的内容,它可以是文本、网址,文件........。然后就可以生成代表它们的二维码。

▲ 这是二维码(已经将内容模糊处理)

你也可以把二维码上传,进行”解码“,然后就可以解析出二维码代表的含义。

5、传统系统是如何登陆认证的?

认识了二维码,我们了解一下移动互联网下的传统登录认证机制。

前面我们说过,为了安全,手机端它是不会存储你的登录密码的。 但是在日常使用过程中,我们应该会注意到,只有在你的应用下载下来后,第一次登录的时候,才需要进行一个账号密码的登录, 那之后呢 即使这个应用进程被杀掉,或者手机重启,都是不需要再次输入账号密码的,它可以自动登录。

其实这背后就是一套基于token的认证机制,我们来看一下这套机制是怎么运行的。

如上图所示:

  • 1)账号密码登录时,客户端会将设备信息一起传递给服务端;
  • 2)如果账号密码校验通过,服务端会把账号与设备进行一个绑定,存在一个数据结构中,这个数据结构中包含了账号ID、设备ID、设备类型等等。

const token = {

  acountid: '账号ID',

  deviceid: '登录的设备ID',

  deviceType: '设备类型,如 iso,android,pc......',

}

然后服务端会生成一个token,用它来映射数据结构,这个token其实就是一串有着特殊意义的字符串,它的意义就在于,通过它可以找到对应的账号与设备信息。

具体是:

  • 1)客户端得到这个token后,需要进行一个本地保存,每次访问系统API都携带上token与设备信息;
  • 2)服务端就可以通过token找到与它绑定的账号与设备信息,然后把绑定的设备信息与客户端每次传来的设备信息进行比较, 如果相同,那么校验通过,返回AP接口响应数据, 如果不同,那就是校验不通过拒绝访问。

从前面这个流程,我们可以看到,客户端不会也没必要保存你的密码,相反,它是保存了token。

可能有些同学会想,这个token这么重要,万一被别人知道了怎么办。

实际上:知道了也没有影响, 因为设备信息是唯一的,只要你的设备信息别人不知道, 别人拿其他设备来访问,验证也是不通过的。

可以说,客户端登录的目的,就是获得属于自己的token。

限于篇幅,这方面的文章,可以详细读一下以下几篇:

IM开发基础知识补课(一):正确理解前置HTTP SSO单点登陆接口的原理

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路》(推荐

那么在扫码登录过程中,PC端是怎么获得属于自己的token呢?不可能手机端直接把自己的token给PC端用!token只能属于某个客户端私有,其他人或者是其他客户端是用不了的。

在分析这个问题之前,我们有必要先梳理一下,扫描二维码登录的一般步骤是什么样的。这可以帮助我们梳理清楚整个过程。

6、扫码登录的详细技术步骤

6.1 大概流程

如上图所示:

  • 1)扫码前,手机端应用是已登录状态,PC端显示一个二维码,等待扫描;
  • 2)手机端打开应用,扫描PC端的二维码,扫描后,会提示“已扫描,请在手机端点击确认”;
  • 3)用户在手机端点击确认,确认后PC端登录就成功了。

可以看到,二维码在中间有三个状态:待扫描、已扫描待确认、已确认。

那么可以想象:

具体解释就是:

  • 1)二维码的背后它一定存在一个唯一性的ID,当二维码生成时,这个ID也一起生成,并且绑定了PC端的设备信息;
  • 2)手机去扫描这个二维码;
  • 3)二维码切换为 已扫描待确认状态, 此时就会将账号信息与这个ID绑定;
  • 4)当手机端确认登录时,它就会生成PC端用于登录的token,并返回给PC端。

好了,到这里,基本思路就已经清晰了,接下来我们把整个过程再具体化一下。

6.2 二维码准备

按二维码不同状态来看, 首先是等待扫描状态,用户打开PC端,切换到二维码登录界面时。

如上图所示:

  • 1)PC端向服务端发起请求,告诉服务端,我要生成用户登录的二维码,并且把PC端设备信息也传递给服务端;
  • 2)服务端收到请求后,它生成二维码ID,并将二维码ID与PC端设备信息进行绑定;
  • 3)然后把二维码ID返回给PC端;
  • 4)PC端收到二维码ID后,生成二维码(二维码中肯定包含了ID);
  • 5)为了及时知道二维码的状态,客户端在展现二维码后,PC端不断的轮询服务端,比如每隔一秒就轮询一次,请求服务端告诉当前二维码的状态及相关信息。

二维码已经准好了,接下来就是扫描状态。

6.3 扫描状态切换

如上图所示:

  • 1)用户用手机去扫描PC端的二维码,通过二维码内容取到其中的二维码ID;
  • 2)再调用服务端API将移动端的身份信息与二维码ID一起发送给服务端;
  • 3)服务端接收到后,它可以将身份信息与二维码ID进行绑定,生成临时token。然后返回给手机端;
  • 4)因为PC端一直在轮询二维码状态,所以这时候二维码状态发生了改变,它就可以在界面上把二维码状态更新为已扫描。

那么为什么需要返回给手机端一个临时token呢?

临时token与token一样,它也是一种身份凭证,不同的地方在于它只能用一次,用过就失效。

在上图中的第三步骤中返回临时token,为的就是手机端在下一步操作时,可以用它作为凭证。以此确保扫码,登录两步操作是同一部手机端发出的。

6.4 状态确认

最后就是状态的确认了。

如上图所示:

  • 1)手机端在接收到临时token后会弹出确认登录界面,用户点击确认时,手机端携带临时token用来调用服务端的接口,告诉服务端,我已经确认;
  • 2)服务端收到确认后,根据二维码ID绑定的设备信息与账号信息,生成用户PC端登录的token;
  • 3)这时候PC端的轮询接口,它就可以得知二维码的状态已经变成了"已确认"。并且从服务端可以获取到用户登录的token;
  • 4)到这里,登录就成功了,后端PC端就可以用token去访问服务端的资源了。

扫码动作的基础流程都讲完了,有些细节还没有深入介绍。

比如二维码的内容是什么?

  • 1)可以是二维码ID;
  • 2)可以是包含二维码ID的一个url地址。

在扫码确认这一步,用户取消了怎么处理? 这些细节都留给大家思考。

7、本文小结

通俗地总结一下本文的扫码登陆逻辑就是:

扫码登录的本质就是:

  • 1)告诉系统我是谁;
  • 2)向系统证明我谁。

在这个过程中,我们先简单讲了两个前提知识:

  • 1)一个是二维码原理;
  • 2)一个是基于token的认证机制。

然后我们以二维码状态为轴,分析了这背后的逻辑: 通过token认证机制与二维码状态变化来实现扫码登录。

需要指出的是,前面的讲的登录流程,它适同样用于同一个系统的PC端,WEB端,移动端。

平时我们还有另外一种场景也比较常见,那就是通过第三方应用来扫码登录,比如极客时间/掘金  都可以选择微信/QQ等扫码登录,那么这种通过第三方应用扫码登录又是什么原理呢?

感兴趣的同学可以思考研究一下,欢迎在评论留下你的见解。

附录:更多IM开发热门知识

新手入门一篇就够:从零开发移动端IM

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

从客户端的角度来谈谈移动端IM的消息可靠性和送达机制

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

腾讯技术分享:社交网络图片的带宽压缩技术演进之路

小白必读:闲话HTTP短连接中的Session和Token

IM开发基础知识补课:正确理解前置HTTP SSO单点登录接口的原理

移动端IM中大规模群消息的推送如何保证效率、实时性?

移动端IM开发需要面对的技术问题

开发IM是自己设计协议用字节流好还是字符流好?

请问有人知道语音留言聊天的主流实现方式吗?

IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

IM消息送达保证机制实现(二):保证离线消息的可靠投递

如何保证IM实时消息的“时序性”与“一致性”?

一个低成本确保IM消息时序的方法探讨

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

谈谈移动端 IM 开发中登录请求的优化

移动端IM登录时拉取数据如何作到省流量?

浅谈移动端IM的多点登录和消息漫游原理

完全自已开发的IM该如何设计“失败重试”机制?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

微信对网络影响的技术试验及分析(论文全文)

即时通讯系统的原理、技术和应用(技术论文)

开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀

QQ音乐团队分享:Android中的图片压缩技术详解(上篇)

QQ音乐团队分享:Android中的图片压缩技术详解(下篇)

腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率

腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)

腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)

如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)

字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8

全面掌握移动端主流图片格式的特点、性能、调优等

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

自已开发IM有那么难吗?手把手教你自撸一个Andriod版简易IM (有源码)

融云技术分享:解密融云IM产品的聊天消息ID生成策略

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

拿起键盘就是干:跟我一起徒手开发一套分布式IM系统

适合新手:手把手教你用Go快速搭建高性能、可扩展的IM系统(有源码)

IM里“附近的人”功能实现原理是什么?如何高效率地实现它?

IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路

IM开发基础知识补课(八):史上最通俗,彻底搞懂字符乱码问题的本质

IM“扫一扫”功能很好做?看看微信“扫一扫识物”的完整技术实现

IM的扫码登录功能如何实现?一文搞懂主流应用的扫码登录技术原理

IM要做手机扫码登录?先看看微信的扫码登录功能技术原理

IM消息ID技术专题(一):微信的海量IM聊天消息序列号生成实践(算法原理篇)

IM消息ID技术专题(二):微信的海量IM聊天消息序列号生成实践(容灾方案篇)

IM消息ID技术专题(三):解密融云IM产品的聊天消息ID生成策略

IM消息ID技术专题(四):深度解密美团的分布式ID生成算法

IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现

IM消息ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)

IM开发宝典:史上最全,微信各种功能参数和逻辑规则资料汇总

IM开发干货分享:我是如何解决大量离线消息导致客户端卡顿的

零基础IM开发入门(一):什么是IM系统?

零基础IM开发入门(二):什么是IM系统的实时性?

零基础IM开发入门(三):什么是IM系统的可靠性?

零基础IM开发入门(四):什么是IM系统的消息时序一致性?

IM开发干货分享:如何优雅的实现大量离线消息的可靠投递

IM开发干货分享:有赞移动端IM的组件化SDK架构设计实践

一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等

>> 更多同类文章 ……

本文已同步发布于“即时通讯技术圈”公众号。

▲ 本文在公众号上的链接是:点此进入。同步发布链接是:http://www.52im.net/thread-3525-1-1.html



作者:Jack Jiang (点击作者姓名进入Github)
出处:http://www.52im.net/space-uid-1.html
交流:欢迎加入即时通讯开发交流群 215891622
讨论:http://www.52im.net/
Jack Jiang同时是【原创Java Swing外观工程BeautyEye】【轻量级移动端即时通讯框架MobileIMSDK】的作者,可前往下载交流。
本博文 欢迎转载,转载请注明出处(也可前往 我的52im.net 找到我)。


只有注册用户登录后才能发表评论。


网站导航:
 
Jack Jiang的 Mail: jb2011@163.com, 联系QQ: 413980957, 微信: hellojackjiang