今天分享的是去年秋招时,抖音面试时有位读者被问到的一个问题,正好看到一篇很好的文章回答了这个问题,分享给大家。
ps:这个问题在面试中比较常见,阿里、腾讯、用友、京东、小红书等大中型企业的面试都问过这个问题。
以下为正文。
前几天在极客时光[1]上看了一个关于二维码的视频,写的很好,这里总结一下。
日常生活中,二维码出现在很多场景中,比如超市支付、系统登录、应用下载等。了解二维码的原理可以为技术人员在技术选型时提供新思路。对于非技术人员来说,除了可以解决他们的疑惑,还可以指导他们更好地识别生活中遇到的各种二维码,防止被骗。
二维码,大家都很熟悉
购物、就餐、乘车时扫码
当扫描二维码时,你可能会有疑问:这个二维码安全吗?它会泄露我的个人信息吗?更高级的用户可能还会考虑:我是否也可以使用二维码来推广我的系统?
这时候你就需要了解二维码背后的技术和逻辑了!
二维码最常见的一个场景就是通过手机应用在PC或者WEB上扫描二维码登录同一个系统。比如在PC上通过手机扫描二维码就可以登录微信,在PC上通过手机扫描二维码就可以登录淘宝。那么下面我们就来看看二维码登录是怎么回事吧!
二维码登录的本质
二维码登录本质上是一种登录认证方式,既然是登录认证,那要做的就只有两件事!
告诉系统我是谁
向系统证明我是谁
比如用账号密码登录,账号告诉系统我是谁,密码向系统证明我是谁;比如用手机验证码登录,手机号告诉系统我是谁,验证码向系统证明我是谁。
那么扫描二维码登录是如何实现这两件事的呢?我们一起来思考一下。
手机APP扫描PC二维码,手机APP确认后,账号在PC上登录成功!这里PC上登录的账号肯定和手机APP是同一个账号,不可能出现手机APP登录的是A账号,扫码登录后PC上登录的是B账号的情况。
所以,第一件事就是告诉系统我是谁,这个比较清楚!
通过扫描二维码,将手机上的账户信息传输到PC上,至于怎么传输,我们后面再讲。
第二件事是向系统证明我是谁。在扫描二维码和登录过程中,用户没有输入密码、验证码或任何其他代码。这怎么证明呢?
有同学可能会疑惑,扫码过程中会不会把密码传输到PC上呢?但是这个不可能,因为太不安全了,而且客户端根本不会存储密码。我们仔细想一想,其实手机APP已经登录过了,也就是说手机通过了登录认证,只要扫码确认是这个手机、这个账号,其实就能间接证明我是谁了。
理解二维码
那么我们该如何确认呢?我们稍后会详细解释,但在此之前我们需要先了解二维码!在了解二维码之前,我们先来看看一维码吧!
所谓一维码,就是条形码,超市里的条形码——相信大家都很熟悉了。条形码其实就是一串数字,里面存储的是商品的序列号。
二维码其实跟条形码类似,只不过二维码里面存储的不一定是数字,也可以是任意一串字符,你可以把它看成是另一种形式的字符串表示。
在搜索引擎中搜索QR code,你会发现很多在线QR code生成工具网站,这些网站可以提供字符串和QR code之间的转换功能,比如 QR Code网站[2]
在左侧的输入框中,你可以输入你的内容,可以是文本,URL,文件等,然后你就可以生成代表它们的二维码。
您也可以上传二维码并对其进行“解码”,然后就可以分析二维码的含义。
系统认证机制
了解了二维码,我们再来了解一下移动互联网下的系统认证机制。
前面我们说过,为了安全起见,手机是不会存储你的登录密码的。但在日常使用中,我们应该注意到,下载应用后,首次登录时只需要输入账号和密码即可。之后,即使应用进程被杀掉或者手机重启,也不需要再次输入账号和密码,它就能自动登录。
其实这背后是一套基于的认证机制,我们来看一下这个机制是如何运作的。
当使用账号和密码登录时,客户端会将设备信息传递给服务端。
如果账号和密码验证通过,服务端会将账号和设备进行绑定,并保存在一个数据结构中,这个数据结构里面包含了账号ID,设备ID,设备类型等。
const token = {
acountid:'账号ID',
deviceid:'登录的设备ID',
deviceType:'设备类型,如 iso,android,pc......',
}
然后服务端会生成一个来映射数据结构,这个其实是一个有特殊含义的字符串,它的意义在于可以用来查找对应的账号和设备信息。
客户端获取到这个之后,需要保存到本地,并且在每次访问系统API的时候携带设备信息。
服务端找到自己绑定的账号和设备信息,然后将绑定的设备信息和客户端每次发送的设备信息进行对比,相同则验证通过,返回AP接口响应数据,不同则验证失败,拒绝访问。
从前面的流程我们可以看出,客户端没有也不需要保存你的密码,相反,是保存了的。有的同学可能会觉得这个这么重要,万一被别人知道了怎么办?其实知道了也没关系,因为设备信息是唯一的,只要别人不知道你的设备信息,用其他设备访问是不会通过验证的。
可以说客户端登录的目的就是为了得到属于自己的东西。
那么在二维码扫描登录过程中,PC端是如何获取自己的二维码的呢?手机端直接把自己的二维码给PC端,这是不可能的!只能是某个客户端私有的,其他人或者其他客户端是无法使用的。在分析这个问题之前,我们需要先理清一下扫描二维码登录的大致步骤,这样才能帮助我们理清整个流程。
扫描二维码登录的一般流程
扫码前手机APP已登录,PC端显示等待扫描的二维码。
在手机上打开APP,在PC上扫描二维码,扫描后会提示“已扫描,请在手机上点击确认”
用户在手机端点击确认,确认后PC端登录成功
可以看到,二维码中间一共有三种状态:等待扫描、扫描完毕等待确认、已确认。
二维码背后必须有一个唯一的ID,在生成二维码的时候也会生成这个ID,并与PC上的设备信息进行绑定。
使用手机扫描此二维码
二维码切换为已扫描并确认状态,账户信息将与此ID绑定。
当手机确认登录后,会生成PC登录并返回给PC。
好的,现在基本思想已经清楚了,我们来具体地讲一下整个过程。
二维码准备
根据二维码的不同状态,第一种是等待扫描状态,此时用户打开PC,切换到二维码登录界面。
PC向服务器发送请求,告诉它要生成用于用户登录的二维码,并将PC设备信息传递给服务器。
服务器收到请求后,生成二维码ID,并将二维码ID与PC设备信息绑定。
然后将二维码ID返回给PC
PC收到二维码ID后,生成二维码(二维码中必须包含ID)
为了及时知道二维码的状态,客户端展示二维码后,PC会不断向服务器进行轮询,例如每秒一次,请求服务器告知二维码当前的状态及相关信息。
二维码已经准备好了,接下来就是扫描。
扫描状态开关
用户使用手机扫描PC上的二维码,从二维码内容中获取二维码ID。
然后调用服务端API将手机端的身份信息和二维码ID发送给服务端
服务器收到后,可以将身份信息和二维码ID进行绑定,生成一个临时的二维码ID,返回给手机。
因为PC一直在轮询二维码状态,如果此时二维码状态发生变化,就可以在界面上更新二维码状态为已扫描
那么为什么需要给手机返回一个临时ID呢?临时ID也是一种身份证明,但是不同的是,它只能使用一次,使用后就会失效。
第三步的临时返回,是为了让手机在下一步中可以作为凭证使用,这样就保证了扫码和登录两个步骤是同一个手机发起的。
状态确认
最后一步是确认状态。
收到临时后手机会弹出一个确认登录界面,当用户点击确认后手机会携带调用服务器的临时接口,告诉服务器我已经确认了
服务器收到确认后,根据二维码ID绑定的设备信息和账号信息,为用户PC生成登录表单。
此时PC端的轮询接口可以知道二维码的状态已经变为“已确认”,并且可以从服务器获取用户的登录信息。
至此登录成功,可以使用后端PC访问服务器资源。
扫码的基本流程已经讲解完毕,但是有些细节还没有深入介绍。
比如,二维码的内容是什么?
如果用户取消了扫码确认步骤该怎么办?这些细节就留给大家去思考吧。
总结
我们从登录的本质出发,探究二维码扫描登录是如何实现的
告诉系统我是谁
向系统证明我是谁
在这个过程中,我们首先简单讲了两个前提条件。
然后我们根据二维码状态来分析这背后的逻辑:扫码登录是通过认证机制和二维码状态变化来实现的。
需要指出的是,以上登录流程适用于同一系统的PC端、WEB端和移动端。
通常我们还有另外一种常见的场景,就是通过第三方应用扫码登录。比如极客时光/掘金可以选择微信/等扫码登录。那么通过第三方应用扫码登录的原理是什么呢?
有兴趣的同学可以思考研究一下,欢迎在评论区留下你的见解。
参考
[1]
带有二维码的 Geek Time 视频:
[2]
草丛二维码网站:
推荐:
点击下方卡片进入公众号
回复“PDF”即可领取PDF版技术面试手册
回复“学习路线”获取4万+字Java学习路线最新版
回复“开源”获取优质Java开源项目合集
免费分享,无任何技巧,有帮助就点个赞吧!