基于Django开发Web微信
引子:
开发Web微信对我们没有实际意义,为啥要开发它是为了让我们通过现有的知识去知道腾讯的微信网页版是怎么做的,分析它里面的一些通信流程,从而模仿他们。
一 Web微信通信流程分析
'''
微信是怎么做的?首先我们登陆微信网页版 “https://wx.qq.com/” ,然后用Django搭建一个登陆页面,微信回车走你有二维码,自己搭的页面走你,没有二维码。那我们是不是想要模仿微信网页版,所以我们也要知道这个二维码怎么来的。
'''
1.访问wx.qq.com获取二维码,然后检查二维码图片的链接,发现每次后缀都会发生变化。
刷新后: 那我们能把它的路径直接copy过来么?是不是不能呀,以为它是在变的。
2.分析network里面的响应数据,jslogin里面的response包含着我们想要的随机码。
# 那我们可以通过对这个网址进行访问获取随机码,然后通过对链接进行拼接,就能保证每次刷新都是同一份随机码
https://login.weixin.qq.com/qrcode/ + 'QRLogin.code'
3.接下来我们要对jslogin这个地址进行访问,发现他每次的后缀都会发生改变,那我们进行猜测也是一个随机码,只不过这个码看起来比较熟悉!你们猜一下它像什么?是不是你们经常看到的时间戳(然后去演示下),只不过这个时间戳是 * 1000的出的int类型。
所以接下里我们又得对jslogin这个链接进行拼接了:
# https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_= + '时间戳'
4.经过分析后再次发现微信的后天隔一段时间不停地发送同一个请求:
# https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=Idzk7j7CnA==&tip=0&r=-147281961&_=1550630346300
'''
需要变得值:
1.uuid=Idzk7j7CnA==
2._=1550630346300
'''
奇怪了,为啥会这样呢?最后发现原来微信后台会隔一段时间发请求判断你用户有没有扫码,扫码的话会显示状态码:201,没有则显示状态码:406。如果重新发送请求也会显示406。扫码成功
腾讯用了一个请求机制叫做轮训机制,就是不停的往服务端发送ajax请求。引出长轮训,如果轮训的话是不是会反复地发请求,这就会使服务器承受着巨大的压力。那长轮询就是设置隔多长时间发送一次请求,并且服务器一直hold住你的请求,腾讯的hold住30秒后再次发送请求。那这样发请求就没那么频繁,对服务器造成的压力就降低了很多。
# 长轮询访问地址
https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=odaPRDNX5A==&tip=0&r=-149192961&_=1550630346321
轮询与长轮询
轮询: 就是浏览器定时向后台发送请求,怎么实现?JS里面是不是有个setiterval()可以每两秒发送一次请求,但是效率很低。
长轮询: 这里一个长轮询地时候一直等着,相当于服务端给你写了一个time.sleep,hold住了这次请求。二维码出来了以后浏览器立即往微信发送一次请求。微信把你的请求给hold住了,最多hold30秒,30秒以后就再次发送一次请求。
长轮询与轮询的比较:
长轮询效率比较高,可以实时拿后台数据,并且对服务器的压力相对较低!
'''
后台写一个长轮询:
有变化的只有 1 和 4,其他都不需要变
1.uuid=odaPRDNX5A==
2.tip=0
3.r=-149192961
4._=1550630346321
'''
状态吗: 408
状态吗: 201
在长轮询的阶段,假如你扫码了,就会返回状态码201并且获取自己的头像图片,接着拿到图片渲染到你的页面上。通过userAvatar获取图片地址。
这就是你想要的图片地址来源。。。
状态吗: 200 扫码并且登陆成功
# 状态码200表示登陆成功给我返回一个redirect_uri
# 此时不知道是用来干嘛的?但是它给你肯定是有目的的,应该是让你跳转到用户主页
# 例子: 支付宝支付后跳转到支付成功页面 那么我们去微信那看下到底给我返回的是什么,
# 有没有给我返回跳转后的请求结果, 清楚缓存后继续测试
跳转的地址1:
# 登陆成功后跳转的地址:
# https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A50oEH3MyI7d2XwV2BgLikxL@qrticket_0&uuid=IdjAm3DB0Q==&lang=zh_CN&scan=1550648853&fun=new&version=v2
# 这个地址并不是我们的主页,而是一个xml文档
<!-- 用户登陆后的xml文档 -->
<error>
<ret>0</ret>
<message></message>
<skey>@crypt_23bb7547_131bebdf5855d4e497f8b8811e848926</skey>
<wxsid>gw2/q1FskP/Tykh1</wxsid>
<wxuin>1684358041</wxuin>
<pass_ticket>GXaeST1uv4HugKXDoSJLDOAvmfU2iPGzvktiCxdgZuQQzsjBypoKwePVDsig2pzq</pass_ticket>
<isgrayscale>1
</isgrayscale>
</error>
跳转的地址2:
# 接着往这个地址发送一次请求,我们来分析这个地址里面携带的pass_ticket我们是不是在哪里见过!其实就是在我们上面登陆的xml里面。pass_ticket里面是不是有一大堆的值。所以我们需要把这些结果保存起来,以后做初始化需要用到。
# https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-165558533&pass_ticket=GXaeST1uv4HugKXDoSJLDOAvmfU2iPGzvktiCxdgZuQQzsjBypoKwePVDsig2pzq
跳转的地址3:
# 这个地址里面的json数据我没猜错的话应该是你微信当前好友的聊天记录。