天天看點

微信協定的研究分析求解

推薦個微信Web版的協定流程:

1.微信伺服器傳回一個會話ID

微信Web版本不使用使用者名和密碼登入,而是采用二維碼登入,是以伺服器需要首先配置設定一個唯一的會話ID,用來辨別目前的一次登入,通過請求位址:

https://login.weixin.qq.com /jslogin?appid=wx782c26e4c19acffb&redirect_uri=https:/ /wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage&fun=new& amp;lang=zh_CN&_=1377482012272(其中1377482012272這個值是目前距離林威治标準時間的毫秒)

伺服器會傳回如下的字元串:

window.QRLogin.code = 200; window.QRLogin.uuid = “DeA6idundY9VKn”;

而這個DeA6idundY9VKn字元串就是微信伺服器傳回給我們的ID。

2.通過會話ID獲得二維碼

既然微信Web版本是通過二維碼進行登入,如何獲得這個随機的二維碼呢?答案就是利用剛才獲得的ID去請求伺服器生成的二維碼,通過上面的ID我們組合得到以下的URL位址:

https://login.weixin.qq.com/qrcode/DeA6idundY9VKn?t=webwx

該請求傳回的便是我們需要的二維碼,此時需要使用者在微信的手機版本中掃描這個二維碼(我就搞不明白微信官方是如何想的,登入Web版本竟然還需要手機微信去配合登入,難道沒有考慮我被迫選擇Web微信就是因為手機不在身邊這樣的情形麼?)

3.輪詢手機端是否已經掃描二維碼并确認在Web端登入

當獲得二維碼之後,就需要使用者去手機端去掃描二維碼,并獲得使用者的授權,此時我們并不知道使用者何時完成這個操作,是以我們隻有輪詢,而輪詢的位址就是:

https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid=DeA6idundY9VKn&tip=1&_=1377482045264(注意UUID和最後時間這兩個參數)

如果伺服器傳回:

window.code=201;

則說明此時使用者在手機端已經完成掃描,但還沒有點選确認;

如果伺服器傳回:

window.redirect_uri=一個URL位址

則說明此時使用者已經在手機端完成了授權過程,儲存下這個URL位址下一步驟中使用。

4.通路登入位址,獲得uin和sid

通過通路上一步驟中獲得的URL位址,可以在伺服器傳回的Cookies中獲得到wxuin和wxsid這兩個值,這兩值在後續的通信過程中都要使用到這兩個值,并且Cookies中也需要包括這兩項。

5.初使化微信資訊

前面的步驟算是完成了這個複雜的登入過程,如果我們需要使用微信就需要獲得目前使用者的資訊、好友清單等,還有一個關鍵的就是同步資訊(後續與伺服器輪詢中需要使用同步資訊),通過通路以下的連結:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=1377482058764(r依然是時間)

通路該連結需要使用POST,并且在Body中帶上以下的JSON資訊:

1

2

{“BaseRequest”:

{“Uin”:“2545437902”,“Sid”:“QfLp+Z+FePzvOFoG”,“Skey”:"",“DeviceID”:“e1615250492”}}

這個JSON串中Uin和Sid分别是上面步驟中獲得的那兩個Cookie值,DeviceID是一個本地生成的随機字元串(分析了官方的總是e+一串數字,是以我們也保持這樣的格式)。

伺服器就會傳回一個很長的JSON串,這其中包括:BaseResponse中的值用來表示請求狀态碼,ContactList主要用來表示聯系人(此列 表不全,隻包括了類似通訊錄助手、檔案助手、微信團隊和一些公衆帳号等,後面會通過另一接口去獲得更全面的資訊),SyncKey是使用者與伺服器同步的信 息,User就是目前登入使用者自己的資訊。

6.獲得所有的好友清單

在上一步驟中已經獲得了部分好友和公衆帳号,如果需要獲得完整的好友資訊,就需要通路以下的連結:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?r=1377482079876(r依然是時間)

通路該連結同樣需要POST方式,但Body為空JSON:{},伺服器對身份的判定是通過Cookies,是以需要保持之前通路的Cookies不被修 改(在Objective-C中會自動儲存相關的Cookies,無需程式特殊處理),在傳回的JSON串中,MemberList中就包含了所有的好友 資訊。

7.保持與伺服器的資訊同步

與伺服器保持同步需要在用戶端做輪詢,該輪詢的URL如下:

https://webpush.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck?callback=jQuery18309326978388708085_1377482079946&r=1377482079876&

sid=QfLp+Z+FePzvOFoG&uin=2545437902&deviceid=e1615250492&synckey=(見以下說明)&_=1377482079876

其中的參數r和_都是time,sid,uin,deviceid與上面步驟的值相對應,此處的synkey是上步步驟獲得的同步鍵值,但需要按一定的規則組合成以下的字元串:

1_124125|2_452346345|3_65476547|1000_5643635

就是将鍵和值用_隔開,不同的鍵值對用|隔開,但記得|需要URL編碼成|,通過通路上面的位址,會傳回如下的字元串:

window.synccheck={retcode:”0”,selector:”0”}

如果retcode中的值不為0,則說明與伺服器的通信有問題了,但具體問題我就無法預測了,selector中的值表示用戶端需要作出的處理,目前已經知道當為6的時候表示有消息來了,就需要去通路另一個接口獲得新的消息。

8.獲得别人發來的消息

當一個步驟中知道有新消息時,就需要去擷取消息内容,通過通路以下的連結:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=QfLp+Z+FePzvOFoG&r=1377482079876

上面連結中的參數sid對應上面步驟中的值,r為時間,通路連結需要使用POST方式,Body中包括JSON串,該JSON串格式如下:

1

2

3

{“BaseRequest” : {“Uin”:2545437902,“Sid”:“QfLp+Z+FePzvOFoG”},

“SyncKey” : {“Count”:4,“List”:[{“Key”:1,“Val”:620310295},{“Key”:2,“Val”:620310303},{“Key”:3,“Val”:620310285},{“Key”:1000,“Val”:1377479086}]},

“rr” :1377482079876};

以下的資訊中BaseRequest中包括的Uin與Sid與上面步驟中的值對應,SyncKey也是上面步驟中獲得的同步鍵值對,rr為時間,通路成功之後伺服器會傳回一個JSON串,其中AddMsgList中是一個數組,包含了所有新消息。

9.向使用者發送消息

使用者主動發送消息,通過以下的URL位址:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid=QfLp+Z+FePzvOFoG&r=1377482079876

上面的sid和r參數不再解釋了,通路該URL采用POST方式,在Body中的JSON串形如以下的格式:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

{

“BaseRequest”:{

“DeviceID” : “e441551176”,

“Sid” : “S8wNi91Zry3024eg”,

“Skey” : “F820928BBA5D8ECA23448F076D2E8A915E1349E9FB4F4332”,

“Uin” : “2545437902”

},

“Msg” : {

“ClientMsgId” : 1377504862158,

“Content” : “hello”,

“FromUserName” : “wxid_2rrz8g8ezuox22”,

“LocalID” : 1377504862158,

“ToUserName” : “wxid_j4nu420ojhsr21”,

“Type” : 1

},

“rr” = 1377504864463

}

其中BaseRequest都是授權相關的值,與上面的步驟中的值對應,Msg是對消息的描述,包括了發送人與接收人,消息内容,消息的類型(1為文本),ClientMsgId和LocalID由本地生成。rr可用目前的時間。

在傳回JSON結果中BaseResponse描述了發送情況,Ret為0表示發送成功。

繼續閱讀