http://mp.weixin.qq.com/qa/index.php?qa=15867&qa_1=%E8%98%91%E8%8F%87%E8%A1%97%E7%BD%91%E7%AB%99%E7%9A%84%E6%89%AB%E4%BA%8C%E7%BB%B4%E7%A0%81%E7%99%BB%E5%BD%95%E6%98%AF%E6%80%8E%E4%B9%88%E5%81%9A%E5%88%B0%E7%9A%84%EF%BC%9Fphp
下面是民間的流程,微信Web版的流程:api
1.微信服務器返回一個會話ID數組
微信Web版本不使用用戶名和密碼登陸,而是採用二維碼登陸,因此服務器須要首先分配一個惟一的會話ID,用來標識當前的一次登陸,經過請求地址:服務器
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&_=1377482012272(其中1377482012272這個值是當前距離林威治標準時間的毫秒)微信
服務器會返回以下的字符串:app
window.QRLogin.code = 200; window.QRLogin.uuid = 「DeA6idundY9VKn」;網站
而這個DeA6idundY9VKn字符串就是微信服務器返回給咱們的ID。ui
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編碼成%7C,經過訪問上面的地址,會返回以下的字符串:
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表示發送成功。