直接上代码
第一步:获取二维码的base64和用户标识qrsig
public function qq()
{
$url = 'https://ssl.ptlogin2.qq.com/ptqrshow?appid=549000912&e=2&l=M&s=4&d=72&v=4&t=0.5409099' . time() . '&daid=5';
$arr = $this->get_curl_split($url);
preg_match('/qrsig=(.*?);/', $arr['header'], $match);
if ($qrsig = $match[1]) {
$this->assign('qrsig', $qrsig);
$this->assign('qrcode', base64_encode($arr['body']));
return $this->fetch(':index');
} else {
$this->error('二维码获取失败');
}
}
第二步:拿到qrsig后,轮询接口,获取二维码状态
public function listenQq()
{
$qrsig = $this->request->param('qrsig');
if (empty($qrsig)) {
$this->error('qrsig不能为空');
}
$url = 'https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&ptqrtoken=' . $this->getqrtoken($qrsig) . '&login_sig=&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-' . time() . '0000&js_ver=10194&js_type=1&pt_uistyle=40&aid=549000912&daid=5&';
$ret = $this->get_curl($url, 0, $url, 'qrsig=' . $qrsig . '; ', 1);
if (preg_match("/ptuiCB\('(.*?)'\)/", $ret, $arr)) {
$r = explode("','", str_replace("', '", "','", $arr[1]));
if ($r[0] == 0) {
preg_match('/uin=(\d+)&/', $ret, $uin);
$openid = $uin[1];
preg_match('/skey=@(.{9});/', $ret, $skey);
preg_match('/superkey=(.*?);/', $ret, $superkey);
$data = $this->get_curl($r[2], 0, 0, 0, 1);
$pskey = null;
if ($data) {
preg_match("/p_skey=(.*?);/", $data, $matchs);
$pskey = $matchs[1];
}
if ($pskey) {
if (isset($_GET['findpwd'])) {
$_SESSION['findpwd_qq'] = $openid;
}
$currentTime = time();
$ip = $this->request->ip(0, true);
$findThirdPartyUser = Db::name("third_party_user")
->where('openid', $openid)
->find();
if ($findThirdPartyUser) {
$userData = [
'last_login_ip' => $ip,
'last_login_time' => $currentTime,
'login_times' => Db::raw('login_times+1'),
];
Db::name("third_party_user")
->where('openid', $openid)
->update($userData);
$data = Db::name("user")->where('id', $findThirdPartyUser['user_id'])->find();
} else {
$userId = Db::name("user")->insertGetId([
'create_time' => $currentTime,
'user_status' => 1,
'user_type' => 2,
'user_nickname' => $r[5],
'avatar' => 'https://s1.ax1x.com/2020/10/09/0BXqIg.jpg', // 默认头像
'last_login_ip' => $ip,
'last_login_time' => $currentTime,
]);
Db::name("third_party_user")->insert([
'openid' => $openid,
'user_id' => $userId,
'third_party' => 'QQ',
'last_login_ip' => $ip,
'last_login_time' => $currentTime,
'create_time' => $currentTime,
'login_times' => 1,
'status' => 1,
]);
$data = Db::name("user")->where('id', $userId)->find();
}
cmf_update_current_user($data);
$this->success('登录成功');
} else {
$this->error('获取相关信息失败');
}
} elseif ($r[0] == 65) {
$this->error('二维码已失效');
} elseif ($r[0] == 66) {
$this->error('二维码未失效');
} elseif ($r[0] == 67) {
$this->error('正在验证二维码');
} else {
$this->error($r[4]);
}
} else {
$this->error($ret);
}
}
第三步:前端展示和轮询
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>扫码登录</title>
<style>
body {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
}
.qrcode {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<h3>请使用QQ扫码</h3>
<img class="qrcode" src="data:image/jpeg;base64,{$qrcode}" />
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
var qrsig = "{$qrsig}";
var url = '/plugin/qrcode_login/index/listenQq?qrsig=' + qrsig;
$(document).ready(function () {
setInterval(function () {
$.ajax({type:"GET",url:url,success:function (res) {
if(res.msg == '登录成功') {
window.location.href = document.referrer; //返回上一页并刷新
}
if(res.msg == '二维码已失效') {
window.location.reload();
}
if(res.msg == '正在验证二维码') {
document.getElementsByTagName("h3")[0].innerHTML = '正在进行登录验证'
}
}});
},2000);
});
</script>
</html>