thinkcmf(thinkphp)实现第四方QQ扫码登录,无需接入QQ互联,安装即可使用

西梁 2020年10月09日 43次浏览

直接上代码

第一步:获取二维码的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>

完整代码地址:https://www.thinkcmf.com/appstore/plugin/410.html