他山之石,可以攻玉,你对产品和架构思想都是来自于生活,也来自你对行业内别的产品和架构的学习,然后才有了创新。今天想从以下几个方面去总结:
- 我们是否了解二维码?
- 二维码是什么?
- 二维码实战
- 微信网页版登录原理
我们是否了解二维码?
我们现在每天都在用二维码,比如微信支付,支付宝支付,扫一扫加好友等,还有推广等。这些没有什么好说的,但是我们平常有没有见过这样的事情,有些公司推广了他们研发的产品,使用了IOS和安卓APP做UI交互的,但是推广APP时用了两个二维码,一个是IOS APP的二维码,一个是安卓APP的二维码,为什么会有这么另类的推广,可否集成到一个二维码呢?与之相反的是我们有见过一个二维码没,用安卓手机、IOS手机、微信和支付宝扫描后得到的结果不一样,这些是怎么回事呢?
还有我们使用微信网页版去登录时(wx.qq.com),我们使用手机已经登录的微信去扫一扫,就可以登录成功了,这是怎么回事?因为我们平常都是输入账号和二维码之后登录的,现在网页版上是从哪里获取到账号和密码的,手机扫描二维码后手机发送给网页版的吗?
二维码是什么?
我们去超市买东西时,商品上都会有一个条形码,收银员一扫描就知道了这个商品的编号和价格等,其实条形码就是对物品的一个编号,有时候收银员扫描不出条形码,还可以输入物品上的数字,这就是一个明证。那二维码其实也是存储了一些信息,只不过比起条形码存的内容更多而已,关于二维码是如何编码的,可以参考《二维码的生成细节和原理》,二维码比起条形码有以下优势:
- 存储内容更多;
- 二维码图上有三个定位矩形,保证了我们可以从任意角度甚至是反面都可以识别二维码;
- 二维码增加了纠错机制,也就是说编码了一些冗余信息,这样即使二维码图有破损和残缺都可以识别出。
二维码实战
比较著名的二维码库主要有zxing、qrcode和zbar,zxing支持java、php、js、python等语言的生成和识别,但是对c++仅支持识别不包含生成(详见zxing-cpp);qrcode支持c、php、python,但是对于c语言来讲仅支持生成。具体实现可以参考我的https://github.com/zhiyong0804/qrcode,这里就不细讲了,从原理上,我们还必须了解图像识别等方面的算法,比如opencv。
微信网页版登录原理
我们使用比较高频的社交软件就是QQ和微信了,当然现在还有,其余的人可能是使用陌陌啊,估计这部分人是因为需求比较大,或者上瘾,使用微信或者QQ,我们现在有没有发现都可以使用二维码进行扫描登录,免去了输入账号和密码的过程,但是通过扫描就能登录,那他们的账号信息是如何传递给客户端(PC客户端、网页客户端)的呢?而且我们仔细去分析,不管是谁去扫描都能登录成功,下面我们就以网页版微信(wx.qq.com)为例来分析:
1. 当我们在浏览器输入wx.qq.com后,网页前端向服务器发起了http请求,微信服务器返回了一个uuid一个字段,然后网页前端发起http登录请求,如下所示:
https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=IZEc0ZwH3w==&tip=0&r=-2022997859&_=1518146428000
同时前端把这个uuid信息编码到了二维码图里,如果我们用在线扫码识别工具可以看到它编码的内容是https://login.weixin.qq.com/l/IZEc0ZwH3w==,此时前端发起的这个http请求是一个http的长连接请求(其实这个http长连接叫法有点不太准,比较直观的是服务端hold on了这个请求,一直没有回应,如果前端没有收到这个回应,大约每过25秒有会请求一次)。
2. 我们使用已经登录微信账号的扫描该二维码,就会获取到uuid,然后手机终端发起http请求,该请求里包含了uuid和token(用户登录授信令牌,对应了用户账户信息)。
3. 后台服务收到了手机客户端的http请求后,依据token信息,知道了用户账户信息,于是再次生成一个token_b,并且通过uuid找到了是网页前端的http的会话,也就是我们说的http长连接,然后给前端http请求回复response(包含了token_b)。
4. 前端拿到token_b(授信令牌)就可以与微信后台服务间进行通信了,包含获取用户信息,此时我们在前端可以看到显示了头像,同时也请求了很多的图片和数据资源:
5. 其实在第三步时微信服务器在回复手机客户端的请求后,还会等待手机客户端的确认“登录”信息,如果确认了,前端才会进行显示。
微信的二维码登录是不是很酷啊?反正我觉得从技术和产品上都比较库,当然现在其他的产品都已经实现了这样的功能,但是你现在清楚了没?我相信你已经明白了。如果对于uuid和token还不是很明白可以看我的另一篇博客《安全开放性云平台架构与设计》。