Ziank的技术博客

有关web微信的一些处理

最近由于某些原因吧,想要找一些关于微信发送消息的协议,最后也没有真正的找到,又懒得自己去抓包进行解析,就查找了一些通过http进行微信通信的文章,这里也对自己了解的做一个简单总结。

web微信的通信过程主要就那么几步,登陆,同步,发送消息等等。因为我只看了发送消息的部分,这里也就只简单说一下发送的方法,不多描述接收消息的想法。如果有人想要了解接收的话,可以查看挖掘微信Web网页版通信的全过程,配合自己进行http抓包可以简单的通过分析进行实现。

  1. 获取二维码。
    大家都知道web微信登录主要是通过手机扫描二维码实现,所以第一步就是获取对应的二维码。
    • 请求uuid,URL地址可以使用https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%%3A%%2F%%2Fwx.qq.com%%2Fcgi-bin%%2Fmmwebwx-bin%%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_={now_time}{now_time}为当前时间。返回的结果格式应为window.QRLogin.code = 200; window.QRLogin.uuid = "QaH7gdt7Jg==";其中uuid就是QaH7gdt7Jg==
    • 根据uuid请求登录二维码,URL地址为https://login.weixin.qq.com/qrcode/{uuid}?t=webwx,返回的结果就是二维码图片的二进制流。
  2. 扫描二维码。
    这里的扫描二维码不是说手机的扫描,而是获取手机的扫描结果过程。这个过程只需要轮询一个URL地址,微信服务器会根据当前扫描状态的不同返回不同的响应结果。这个URL地址为https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid={uuid}&tip=1&_={now_time}
    • 如果响应结果返回window.code=201;说明用户已经扫描完成,但是还没有登录;
    • 如果响应结果返回window.redirect_uri={redirect_url}格式,则说明用户已近登录。
  3. 获取uin,sid和ticket
    • 如果只是简单的发送文字消息,ticket是不需要使用的。
    • 这一步主要是访问上一步返回的{redirect_url},我在实际访问时添加了&fun=new,实际中可根据需要自行判断使用old还是new。在服务器返回的cookie中会包含wxuin,wxsid,webwx_data_ticket等字段,根据需要把这些内容记录下来。
  4. 初始化微信信息
    所谓的初始化微信信息就是获取一些当前用户的信息,访问的URL地址为https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r={now_time}。需要注意的是:
    • 访问该链接需要使用POST,并且在Body中带上以下的JSON信息:{"BaseRequest":{"Uin":"2545437902","Sid":"QfLp+Z+FePzvOFoG","Skey":"","DeviceID":"e1615250492"}}。这个JSON串中Uin和Sid分别是上面步骤中获得的那两个Cookie值,DeviceID是一个本地生成的随机字符串(分析了官方的总是e+一串数字,所以我们也保持这样的格式)。
    • 服务器会返回一个很长的JSON串,其中主要包括有BaseResponse(相应返回码等信息),ContactList(常用联系人),SyncKey(用于和服务器同步消息),User(当前用户的信息),SKey(用于后面发送消息认证使用)等内容。
  5. 获取通讯录列表
    在初始化微信信息时返回的联系人列表并不全,需要用这一步的接口才可以获取全部的联系人列表。接口URL地址为https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?r={now_time}。这一步也需要使用POST,但是POST内容只需要设置为空JSON({})即可。在返回的JSON串中,MemberList中就包含了所有的好友信息。
  6. 发送文字信息
    发送消息主要通过URL地址https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid={sid}&r={now_time}。访问该URL采用POST方式,在Body中的JSON串形如以下的格式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"BaseRequest" : {
"DeviceID" : "{DeviceID}",
"Sid" : "{sid}",
"Skey" : "{skey}",
"Uin" : "{uin}"
},
"Msg" : {
"ClientMsgId" : {clientMsgId},
"Content" : "{{messageContent}",
"FromUserName" : "{currentUserName}",
"LocalID" : {localId},
"ToUserName" : "{toUserName}",
"Type" : 1
},
"rr" = {now_time}
}

其中BaseRequest都是授权相关的值,与上面的步骤中的值对应,Msg是对消息的描述,包括了发送人与接收人,消息内容,消息的类型(1为文本),ClientMsgId和LocalID由本地生成。rr可用当前的时间。
在返回JSON结果中BaseResponse描述了发送情况,Ret为0表示发送成功。

我了解的基本也只有这些了,如果以后有兴趣做新的了解的再继续描述吧。

参考资料:
《挖掘微信Web网页版通信的全过程》
微信Post/Get的封包,论坛还没有发布
网页微信客户端封包大全