实现微信登录,不一定要认证微信开放平台。
话不多说,直接上图。
先看登录二维码的分析,可以清楚看到页面先后加载了网页、图片、CSS、Javascript等资源文件,包括二维码图片。
然后仔细观察会发现,网页会一直在异步请求一个链接,这个链接其实就是在监听服务器,如果有人用微信客户端授权成功,则会返回成功的信息然后跳转;否则继续监听。
这个过程就是整个网页最重要的部分了,通过不断请求来监听状态。所以需要重点分析此请求。
从图中我们还可以看到,右侧,每个请求都是用了25s左右。为什么要这么长时间呢?
由于监听和登录操作肯定是短时间内必须完成的,比如我扫完二维码确认登录了,这个页面就要在短时间内做出响应。如果要做到这样,最简单的方法就是通过Javascript定时器,每隔几秒请求服务器并获取状态(事实上我同时也研究过新浪微博的扫二维码登录,它就是这样做的,每隔3-4秒左右请求一次)。然而这样会直接导致的问题就是,服务器会产生非常高的并发,小用户级别的服务器还没什么,但是像微信这种需要服务庞大用户群的服务器,就必须做这方面的优化。
所以微信的采用的做法就是减少请求并增加响应时间,实现的原理大概就是在服务器端接收到请求后,内部加个定时器不断检查用户授权的状态,如果检测到用户授权则马上响应给网页端;否则继续检查;当时间累积到25秒左右,不论成不成功都终止检测并立即响应给网页端。
好了,我们接下来继续观察这个请求的参数:
可以看到总共有五个参数:
-
loginicon :布尔值
-
uuid:字符串
-
tip :正整数
-
r:负整数
-
_:正整数
从字面上来理解的话,
第一个参数大概意思是,是否要有登录图标(true=>要,false=>不要);
第二个参数,是指二维码的值,随便测试下就知道了;
第三个参数,应该是指是否要提示(1=>要,0=>不要);
第四个参数,应该是一个随机数(random);
第五个参数,不难看出这是个Unix时间戳。随机数和时间戳跟安全机制有关吧,防止相关的攻击,如重放攻击。
这几个参数当中,最重要的是当然是uuid了,因为这是用来向服务器请求授权状态的凭借。并且这个uuid必须是唯一不重复的,不然试想下,两个人在不同的电脑下浏览到了同一个二维码,有人授权登录了,可能会是在另一个人电脑上登录微信的网页版。所以说这个唯一的uuid是专门用来绑定一个微信账号的授权的。
因为uuid一般是随机生成的,但是像这里的这串字符,观察最后两个字符“==”,又像是经过某个加密算法产生的,不过这并不太重要,确保到uuid的唯一不重复性就行了。至于r这个参数,我个人猜测这是个随机数。最后一个参数是用来做超时验证操作的,确保一个uuid只在短时间内有效,如果你仔细观察,会发现二维码登录页在几分钟内不登录,那么它会自动刷新然后更新过另外一个二维码。最后利用这三个进行某种算法之后生成签名(下面提到的ticket值)返回给客户端。
接下来我们看看这个请求的返回值:
从图中我们可以看到返回的是一条Javascript语句,有个状态码408,这个就是表示用户还没有用微信客户端APP授权,需要继续请求监听状态。如果是授权成功,则返回200,然后登录页会跳转到后台:
window.code=200;
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AV09Uzr8oDEF1xoAcaOdNUi@articket_0&uuid=wdBJJLlfaQ==&lang=zh_CN&scan=1431123223";
ticket值就是服务器生成的用户签名,理解为access_token即可。
再来看看微信客户端APP扫描二维码后的页面:
当扫描成功二维码后,会弹出授权窗口,询问是否授权登录。
换个二维码扫描软件可以得到登录时候的二维码字符串实际值如图。经过多次试验可以知道前半段不变的,只有后面的参数会变(即uuid值)。
所以分析得到微信客户端的步骤是这样的:
1.扫描二维码(扫一扫)
2.如果字符串前半段是https://login.weixin.qq.com/l/,则弹出授权窗口
3.如果点击确定,再向服务器请求改变这个uuid的状态
完整的流程图:
至此,整个的扫二维码登录流程就完成了。
至于如何利用在此剖析的原理进行二次开发和利用,就尽情发挥你的聪明才智吧。
![]() |
![]() |
不收钱 | 加好友 |
、
龟龟
/
/ - 阅读量
Published under(CC) BY-NC-SA 3.0 CN.