微信扫描二维码登录网页是什么原理,前后两个事件是如何联系的?

关注者
1,652
被浏览
306,336
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

微信和airdroid都有扫描二维码登录的功能,实现略有差别。

如果你用普通的二维码扫描工具扫描它们的二维码,微信得到一个网址,airdroid得到一个字符串,但是里面都会有一个唯一的ID,这一点是共同的。

微信的方案是:

  1. 在网页生成这个二维码的时候,网页就开始用ajax长轮询,对服务器请求这个UID的扫描记录,如果没有,在特定时长后(目前是27秒左右)会接到状态码408,表示应该继续下一次请求,如果接到201,那么就进入第3步
  2. 什么时候有201呢,微信客户端一旦扫描了这个二维码,就会向解出来的网址发起请求,通知扫描成功(当然这个网址做了来源验证)。服务器一接收到这个请求,就从当前的查询长连接里面立即把201返回过去(如果一直没有请求,那么会在30秒内把408返回去,这就是1里面提到的两个状态码的由来)
  3. 得到状态码201后,通知服务器,客户端由此也进入一个新的页面(就是那个要你点确认的按钮),原理跟上一步相同(长轮询)。这个时候你只要点击确认,服务器就开始给该客户端的用户进行自动登录,并把用户信息在这一步通过当前的某个上行的长轮询给返回出去。当然返回的方式不再是什么状态码了,而是header里面的Set-Cookie,咋就内容其实也相当于状态码:<error><ret>0</ret><message>OK</message><skey>xxxx</skey></error>
  4. 这个时候浏览器就可以成功地用微信认可的任何一种认证方式(通过返回的skey和cookie里面的信息)来请求用户数据了。

之所以要提一下airdroid,是因为它在有些地方是不同的,所以,扫描二维码登录这回事,在保证安全的情况下,实现方式是看你的想象力了。

  1. 首先,扫描二维码只得到字符串而不是网址,避免了鉴权网址外泄
  2. 其次,浏览器是能用web socket来和服务器进行通讯的,避免了长轮询(微信是考虑到中国用户的浏览器不支持ws的居多吧。这里可以顺便介绍一下微软的signalR方案,它可以根据客户端浏览器的支持情况进行自动从ws降到long pool,微信团信应该是看到这个需求没多大的意义,干脆直接用最原始的实现吧,毕竟不是做一个库)
  3. 更多细节我就懒得跟踪了,哪天自己也有同样的需求再研究吧