QQ二维码登录API源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
error_reporting(0);
header('Content-type: application/json; charset=utf-8');

function request_http($url, $type=0, $post_data='', $ua='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.58', $cookie='', $header=array(), $redirect=true){
// 初始化
$curl = curl_init();
// 网址
curl_setopt($curl,CURLOPT_URL, $url);
// Ua
if (!empty($ua)) {
$header[] = 'User-Agent:'.$ua;
}
// Cookie
if (!empty($cookie)) {
$header[] = 'Cookie:'.$cookie;
}
// 请求头
if (!empty($ua) or !empty($cookie) or !empty($header)) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
}
// Post数据
if($type == 1){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
}
// 重定向
if (!$redirect) {
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
}
// 过SSL验证证书
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
// 将头部作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, true);
// 以变量形式存储返回数据
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// 请求,存储数据
$return = curl_exec($curl);
// 分割头部和身体
if (curl_getinfo($curl, CURLINFO_HTTP_CODE) == '200') {
$return_header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$return_header = substr($return, 0, $return_header_size);
$return_data = substr($return, $return_header_size);
}
// 关闭
curl_close($curl);
// 返回数据
return [$return_header, $return_data];
}

function return_result($state, $information) {
$result = array(
'state'=>$state,
'information'=>$information
);
exit(stripslashes(json_encode($result, JSON_UNESCAPED_UNICODE)));
}

function get_middle_text($text, $text_left, $text_right) {
$left = strpos($text, $text_left);
$right = strpos($text, $text_right, $left);
if ($left < 0 or $right < $left) {
return False;
}
return substr($text, $left + strlen($text_left), $right - $left - strlen($text_left));
}

function get_ptqrtoken($qr_sig) {
$len = strlen($qr_sig);
$hash = 0;
for ($count = 0; $count < $len; $count++) {
$hash += (($hash << 5) & 2147483647) + ord($qr_sig[$count]) & 2147483647;
$hash &= 2147483647;
}
return $hash & 2147483647;
}

function get_result_data($qr_sig){
$state_data = request_http('https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://qzs.qzone.qq.com/qzone/v5/loginsucc.html?para=izone&from=iqq&ptqrtoken='.get_ptqrtoken($qr_sig).'&ptredirect=1&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-'.time().'&js_ver=10233&js_type=1&login_sig='.$qr_sig.'&pt_uistyle=40&aid=549000912&daid=5', null, null, null, 'qrsig='.$qr_sig)[1];
if (strpos($state_data, '未失效')) {
return '未失效';
} elseif (strpos($state_data, '认证中')) {
return '认证中';
} elseif (strpos($state_data, '登录成功')) {
$ptuicb_url = get_middle_text($state_data, "'0','0','", "','1',");
$ptuicb_header = request_http($ptuicb_url, null, null, null, null, null, false)[0];
$cookie = array(
'uin'=>get_middle_text($ptuicb_header, 'uin=', ';'),
'skey'=>get_middle_text($ptuicb_header, 'skey=', ';'),
'p_uin'=>get_middle_text($ptuicb_header, 'p_uin', ';'),
'p_skey'=>get_middle_text($ptuicb_header, 'p_skey=', ';'),
'pt4_token'=>get_middle_text($ptuicb_header, 'pt4_token=', ';')
);
$information = array(
'state'=>'已登录',
'cookie'=>$cookie
);
return $information;
} elseif (strpos($state_data, '已失效')) {
return '已失效';
} else {
return '未知错误';
}
}

function get_login_data(){
$return = request_http('https://ssl.ptlogin2.qq.com/ptqrshow?appid=549000912&e=2&l=M&s=3&d=72&v=4&t='.time().'&daid=5&pt_3rd_aid=0');
$qr_sig = get_middle_text($return[0], 'qrsig=', ';');
$qr_code = 'data:image/jpeg;base64,'.base64_encode($return[1]);
return [$qr_sig, $qr_code];
}

$type = $_REQUEST['type'];
$qr_sig = $_REQUEST['qr_sig'];
if (($type != 'get' and $type != 'result') or ($type != 'get' and empty($qr_sig))) {
return_result(100, '参数错误');
}
if ($type == 'get') {
$login_data = get_login_data();
$information = array(
'qr_sig'=>$login_data[0],
'qr_code'=>$login_data[1]
);
} else {
$information = get_result_data($qr_sig);
}
return_result(200, $information);
?>
名称 必填 说明
type get代表登录数据,result代表结果
qrsig 存在登录数据中,type为result时必填