Web QQ 的请求交互过程

获取安全参数

发送http GET请求:

https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=5&mibao_css=m_webqq&appid=1003903&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20130830001

在响应的HTML中通过正则表达式  /var g_login_sig=encodeURIComponent\(“(.+?)”\);/)获取到安全参数sign.

在上面的URL中,有个参数要注意 appid=1003903这个参数在下面的步骤中经常遇到.

 

处理验证码

首先检验是否需要输入验证码

发送HTTP GET请求

 ”https://ssl.ptlogin2.qq.com/check?uin={0}&appid={1}&js_ver=10038&js_type=0&login_sig={2}&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.5331138293443659″.format(QQ, APPID, sign);

上面的请求中,参数QQ指要登录的QQ号码,APPID始终为1003903,sign是上步中获取到的安全参数.

响应类似于下面的格式:

pt_checkVC('0', '!B55', '\x00\x00\x00\x00\xa6\xce\xef\xfe')

如果第一个数字为0,则表示第二个参数做为验证码;如果为1,则表示要通过图片输入验证码,验证码图片的请求如下:

发送https GET请求

“https://ssl.captcha.qq.com/getimage?aid={0}&r={1}&uin={2}”.format(APPID, Math.random(), QQ)

获取图片后可以得到验证码.

第一次登录

发送https GET请求:

‘https://ssl.ptlogin2.qq.com/login?u={0}&p={1}&verifycode={2}&webqq_type=10&remember_uin=1&login2qq=1&aid={3}&u1={4}&h=1&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=1-41-15424&mibao_css=m_webqq&t=1&g=1&js_type=0&js_ver=10038&login_sig={5}’.format(QQ, p, vc, APPID, “http%3A%2F%2Fweb.qq.com%2Floginproxy.html%3Flogin2qq%3D1%26webqq_type%3D10″, sign);

参数QQ指QQ号,p指加密后的密码,vc是验证码.

该请求必须设置Refer为:’https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164′.

如果登录成功,会返回ptuiCB('0',....),从返回的cookie中取出ptwebqq.

密码的加密算法在js中,地址是:https://ui.ptlogin2.qq.com/js/10043/comm.js?ptui_identifier=000E012E3A89FB8098A4F8D0E9B21E4FF2947BF9AD24272D7C18A9AC29

加密算法的大致如下:

function getEncPass(q, p, v){
var I = hexchar2bin(md5(p));
var H = md5(I + hexchar2bin(pad(q.toString(16),16)));
return md5(H + v.toUpperCase());
}

其中,q为Q号,p为密码,v是验证码.

这步完了以后只是登录了网站,采用QQ单点认证机制的网站都可以通过的原理登录.

登录成功后返回的字符串中有一个url,以HTTP GET请求方式发送该请求,在响应中会返回两个重要的Cookie:p_skey,pt4_token

第二次登录

发送http POST请求:

http://d.web2.qq.com/channel/login2′

请求的headers必须设置content-type为application/x-www-form-urlencoded; charset=UTF-8, referer 为http://d.web2.qq.com/proxy.html?v=20110331002&callback=2.同时把上个请求的cookie也发送回去.

该请求的post参数有三个’{“status”:”online”,”ptwebqq”:”{0}”,”passwd_sig”:”",”clientid”:”{1}”,”psessionid”:null}’.format(PTWebQQ, ClientID);

请求会返回一个JSON格式的字符串,属性retcode为0则表示登录成功.

{"retcode":0,
  "result":
      {
       "uin":10897944,"cip":1959559061,"index":1075,"port":40036,"status":"online",
       "vfwebqq":"963856c05954b2f1a0b1f4efff16cc605ce3a1b84792ac678dee4b919c1a",
       "psessionid":"c53856c05954b2f1a0b1f4efff16cc605ce3a1b84792ac678dee4b919c1a","user_state":0,"f":0
      }
}

登录成功后,将上面JSON中的vfwebqq和psessionid取出来,供下面的请求使用.

获取好友列表

发送HTTP POST请求

http://s.web2.qq.com/api/get_user_friends2

POST参数为:

r {“h”:”hello”,”hash”:”1FD22A64″,”vfwebqq”:”2445fac910fd4f2e1c01a5fcab36d13a024ccb75abed5360dbf6393c58670cb896bb578e86d3d9ee”}

请求headers需要设置cookie,cookie必须有三个值p_uin, p_skey, pt4_token, ptwebqq.

p_uin为字母o+QQ号的10位形式(不足10位前面补零),如o1624240747

序列化以后为’r=%7B%22h%22%3A%22hello%22%2C%22hash%22%3A%221FD22A64%22%2C%22vfwebqq%22%3A%222445fac910fd4f2e1c01a5fcab36d13a024ccb75abed5360dbf6393c58670cb896bb578e86d3d9ee%22%7D’;

hash通过js算出来的一个值,该算法经常会变,这儿就不列出来了.

请求成功后返回好友列表.

接收好友消息

Web QQ通过不断发送poll2轮询获取好友消息

发送HTTP POST请求:

http://d.web2.qq.com/channel/poll2

POST参数

{r:’{“clientid”:”{0}”,”psessionid”:”{1}”,”key”:0,”ids”:[]}’.format(ClientID, PSessionID),clientid:ClientID, psessionid:PSessionID}

clientid为随机生成的客户端ID, 在Web QQ 所有过程中应该保持一致.

请求headers必须设置

headers : {‘content-length’:post_data.length,’content-type’:'application/x-www-form-urlencoded; charset=UTF-8′,referer : ‘http://d.web2.qq.com/proxy.html?v=20110331002&callback=1&id=3′},

cookie不需要

请求返回一个JSON字符串

{"retcode":0,"result":[{"poll_type":"buddies_status_change","value":{"uin":3983012188,"status":"online","client_type":1}}]}
retcode为0表示获取成功.
poll_type这儿列举几种可能的值:
message : 正常的消息
kick_message : 被踢下线
buddies_status_change : 好友在线状态改变
input_notify : 正在输入
tips : 提示信息

各种消息的构造就不说了.

给好友发送消息

发送HTTP POST请求

http://d.web2.qq.com/channel/send_buddy_msg2

post参数为

{
r : r,
clientid : ClientID,
psessionid : PSessionID
})

r为一个字符串,形式如:

‘{“to”:’ + uin +’,”face”:579,”content”:”[\\"' + result + '\\\\n\\",[\\"font\\",{\\"name\\":\\"微软雅黑\\",\\"size\\":\\"10\\",\\"style\\":[0,0,0],\\”color\\”:\\”000000\\”}]]”,”msg_id”:33470003,”clientid”:”‘+ClientID+’”,”psessionid”:”‘+PSessionID+’”}’

其中uin 指好友的临时号码,获取好友列表的时候可以取的到.

请求的headers必须设置referer为’http://d.web2.qq.com/proxy.html?v=20110331002&callback=1&id=2′,不需要设置cookie

你可能感兴趣的:(Web QQ 的请求交互过程)