首页 >后端开发 >PHP问题 >PHP怎么实现扫码登录QQ

PHP怎么实现扫码登录QQ

藏色散人
藏色散人原创
2022-11-21 09:27:182047浏览

PHP实现扫码登录QQ的方法:1、通过“public function QRcode(){...}”方法获取登录验证码;2、动态传入QQ微信的类名字符串快速实例化;3、生成二维码并轮询检测二维码状态即可。

PHP怎么实现扫码登录QQ

本教程操作环境:Windows7系统、PHP8.1版、Dell G3电脑。

PHP怎么实现扫码登录QQ?

分享一下,PHP实现第四方QQ微信扫码登陆,不接入qq互联以及微信开发者平台就可以实现用户对接鹅厂,phpQQ微信扫码登陆 

自己抓的QQ包以及整合了网上一些已经封装好了的代码

具体如下:

QQ:

<?php
class QQ extends Curl_Api
{
    //获取登录验证码
    public function QRcode()
    {
        $url=&#39;https://ssl.ptlogin2.qq.com/ptqrshow?appid=549000912&e=2&l=M&s=4&d=72&v=4&t=0.5409099&#39;.time().&#39;&daid=5&#39;;
        $arr=$this->get_curl_split($url);
        preg_match(&#39;/qrsig=(.*?);/&#39;,$arr[&#39;header&#39;],$match);
        if($qrsig=$match[1])
            return array(&#39;code&#39;=>200,&#39;qrsig&#39;=>$qrsig,&#39;data&#39;=>base64_encode($arr[&#39;body&#39;]));
        else
            return array(&#39;code&#39;=>400,&#39;msg&#39;=>&#39;二维码获取失败&#39;);
    }
    public function ListenQR($qrsig)
    {
        $qrsig = $qrsig[0];
        if(empty($qrsig))return array(&#39;code&#39;=>-1,&#39;msg&#39;=>&#39;qrsig不能为空&#39;);
        $url=&#39;https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&ptqrtoken=&#39;.$this->getqrtoken($qrsig).&#39;&login_sig=&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-&#39;.time().&#39;0000&js_ver=10194&js_type=1&pt_uistyle=40&aid=549000912&daid=5&&#39;;
        $ret = $this->get_curl($url,0,$url,&#39;qrsig=&#39;.$qrsig.&#39;; &#39;,1);
        if(preg_match("/ptuiCB\(&#39;(.*?)&#39;\)/", $ret, $arr)){
            $r=explode("&#39;,&#39;",str_replace("&#39;, &#39;","&#39;,&#39;",$arr[1]));
            if($r[0]==0){
                preg_match(&#39;/uin=(\d+)&/&#39;,$ret,$uin);
                $uin=$uin[1];
                preg_match(&#39;/skey=@(.{9});/&#39;,$ret,$skey);
                preg_match(&#39;/superkey=(.*?);/&#39;,$ret,$superkey);
                $data=$this->get_curl($r[2],0,0,0,1);
                if($data) {
                    preg_match("/p_skey=(.*?);/", $data, $matchs);
                    $pskey = $matchs[1];
                }
                if($pskey){
                    if(isset($_GET[&#39;findpwd&#39;])){
                        $_SESSION[&#39;findpwd_qq&#39;]=$uin;
                    }
                    return array(&#39;code&#39;=>200,&#39;uin&#39;=>$uin,&#39;skey&#39;=>&#39;@&#39;.$skey[1],&#39;pskey&#39;=>$pskey,&#39;superkey&#39;=>$superkey[1],&#39;nick&#39;=>$r[5]);
                }else{
                    return array(&#39;code&#39;=>201,&#39;msg&#39;=>&#39;登录成功,获取相关信息失败!&#39;.$r[2]);
                }
            }elseif($r[0]==65){
                return array(&#39;code&#39;=>400,&#39;msg&#39;=>&#39;二维码已失效。&#39;);
            }elseif($r[0]==66){
                return array(&#39;code&#39;=>202,&#39;msg&#39;=>&#39;二维码未失效。&#39;);
            }elseif($r[0]==67){
                return array(&#39;code&#39;=>302,&#39;msg&#39;=>&#39;正在验证二维码。&#39;);
            }else{
                return array(&#39;code&#39;=>401,&#39;msg&#39;=>$r[4]);
            }
        }else{
            return array(&#39;code&#39;=>403,&#39;msg&#39;=>$ret);
        }
  
    }
    private function getqrtoken($qrsig){
        $len = strlen($qrsig);
        $hash = 0;
        for($i = 0; $i < $len; $i++){
            $hash += (($hash << 5) & 2147483647) + ord($qrsig[$i]) & 2147483647;
            $hash &= 2147483647;
        }
        return $hash & 2147483647;
    }
}

 

  微信:

<?php
class Wechat extends Curl_Api
{
    //获取验证码
    public function QRcode()
    {
        $url = "https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&fun=new&lang=zh_CN";
        $uuid = $this->get_curl($url);
//        var_dump($uuid);
        $uuid = substr($uuid,strpos($uuid,&#39;"&#39;)+1,-2);
        $url = "https://login.wx.qq.com/qrcode/{$uuid}?t=webwx";
        $qrcode = file_get_contents($url);
        $result = [&#39;code&#39;=>200,&#39;uuid&#39;=>$uuid,&#39;qrcode&#39;=>base64_encode($qrcode)];
        return $result;
    }
    public function ListenQR($uuid)
    {
        $paras[&#39;ctime&#39;] = 1000;
        $paras[&#39;rtime&#39;] = 1000;
        $paras[&#39;refer&#39;] = &#39;https://wx2.qq.com/&#39;;
        $api = &#39;https://login.wx2.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=&#39; . $uuid[0] . &#39;&tip=0&#39;;
        $body = $this->curl($api, $paras);
        preg_match(&#39;/(\d){3}/&#39;, $body, $code);
        preg_match(&#39;/redirect_uri="(.*?)"/&#39;, $body, $url);
        if ($code[0] == &#39;200&#39;) {
            $body = $this->curl($url[1]);
            preg_match(&#39;/<wxuin>(\d*?)<\/wxuin>/&#39;, $body, $wxuin);
            $ret[&#39;code&#39;] = 200;
            $ret[&#39;data&#39;][&#39;uin&#39;] = $wxuin[1];
            $ret[&#39;data&#39;][&#39;type&#39;] = &#39;wx&#39;;
            $ret[&#39;msg&#39;] = &#39;登录成功&#39;;
        } else {
            $ret[&#39;code&#39;] = 408;
            $ret[&#39;msg&#39;] = &#39;请使用手机微信扫码登录&#39;;
        }
        return $ret;
    }
}

  为了方便跳用,这里我又封装了一个类

动态传入QQ微信的类名字符串快速实例化

Tencent类:

<?php
Class Tencent{
    protected $path = __DIR__ . &#39;/&#39;;
     private $cl;
     /*
      * 动态传入QQ或WX字符串,自动转换对应的api类登录
      */
    public function __construct($type)
    {
        //注册自动加载函数
        spl_autoload_register([$this,&#39;Psr4Autoload&#39;]);
        //引入curl
        $this->cl = new $type();
    }
    public function Psr4Autoload($class)
    {
    $class_file = $this->path .&#39;/&#39;. $class . &#39;.php&#39;;
    if (file_exists($class_file))
    {
        include "$class_file";
    }else{
        die(&#39;类文件&#39;.$class_file .&#39;不存在&#39;);
    }
    }
    public function QRcode()
    {
        return call_user_func([$this->cl,__FUNCTION__]);
    }
    public function ListenQR(...$args)
    {
        return call_user_func([$this->cl,__FUNCTION__],$args);
    }
    public function __call($name, $arguments)
    {
       call_user_func_array([$this->cl,$name],(array)$arguments);
    }
}

  以及最后一个curl类:

<?php
class Curl_Api
{
    public $ua = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";
      
     public function get_curl($url,$post=0,$referer=0,$cookie=0,$header=0,$ua=0,$nobaody=0){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $httpheader[] = "Accept: application/json";
        $httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
        $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
        $httpheader[] = "Connection: keep-alive";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
        if($post){
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        }
        if($header){
            curl_setopt($ch, CURLOPT_HEADER, TRUE);
        }
        if($cookie){
            curl_setopt($ch, CURLOPT_COOKIE, $cookie);
        }
        if($referer){
            curl_setopt($ch, CURLOPT_REFERER, $referer);
        }
        if($ua){
            curl_setopt($ch, CURLOPT_USERAGENT,$ua);
        }else{
            curl_setopt($ch, CURLOPT_USERAGENT,$this->ua);
        }
        if($nobaody){
            curl_setopt($ch, CURLOPT_NOBODY,1);
  
        }
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_ENCODING, "gzip");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        $ret = curl_exec($ch);
        curl_close($ch);
        return $ret;
    }
    function curl($url, $paras = array()) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $httpheader[] = "Accept:*/*";
        $httpheader[] = "Accept-Encoding:gzip,deflate,sdch";
        $httpheader[] = "Accept-Language:zh-CN,zh;q=0.8";
        $httpheader[] = "Connection:close";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
        if ($paras[&#39;ctime&#39;]) { // 连接超时
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $paras[&#39;ctime&#39;]);
        }
        if ($paras[&#39;rtime&#39;]) { // 读取超时
            curl_setopt($ch, CURLOPT_TIMEOUT_MS, $paras[&#39;rtime&#39;]);
        }
        if ($paras[&#39;post&#39;]) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $paras[&#39;post&#39;]);
        }
        if ($paras[&#39;header&#39;]) {
            curl_setopt($ch, CURLOPT_HEADER, true);
        }
        if ($paras[&#39;cookie&#39;]) {
            curl_setopt($ch, CURLOPT_COOKIE, $paras[&#39;cookie&#39;]);
        }
        if ($paras[&#39;refer&#39;]) {
            if ($paras[&#39;refer&#39;] == 1) {
                curl_setopt($ch, CURLOPT_REFERER, &#39;http://m.qzone.com/infocenter?g_f=&#39;);
            } else {
                curl_setopt($ch, CURLOPT_REFERER, $paras[&#39;refer&#39;]);
            }
        }
        if ($paras[&#39;ua&#39;]) {
            curl_setopt($ch, CURLOPT_USERAGENT, $paras[&#39;ua&#39;]);
        } else {
            curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
        }
        if ($paras[&#39;nobody&#39;]) {
            curl_setopt($ch, CURLOPT_NOBODY, 1);
        }
        curl_setopt($ch, CURLOPT_ENCODING, "gzip");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $ret = curl_exec($ch);
        curl_close($ch);
        return $ret;
    }
     public function get_curl_split($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $httpheader[] = "Accept: */*";
        $httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
        $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
        $httpheader[] = "Connection: keep-alive";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
        curl_setopt($ch, CURLOPT_HEADER, TRUE);
        curl_setopt($ch, CURLOPT_USERAGENT,$this->ua);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_ENCODING, "gzip");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        $ret = curl_exec($ch);
        $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($ret, 0, $headerSize);
        $body = substr($ret, $headerSize);
        $ret=array();
        $ret[&#39;header&#39;]=$header;
        $ret[&#39;body&#39;]=$body;
        curl_close($ch);
        return $ret;
    }
}

  大致调用的流程

1、保存四个类到文件里面

2、引入文件

3、单独写两个接口,一个生成qr码(base64),一个轮询二维码扫码状态

4、用户扫码成功后、会返回一个QQ号火微信唯一id

5、这里我只演示一个微信扫码登陆的例子

生成二维码并轮询检测二维码状态 login.php :

<?php
//我这里只引入了一个文件的原因是因为Wechat和QQ类不用引入、只需要把Curl_Api请求类引入进来就好,但我Tencent类内已经引入了。所以这里我只需要引入一个文件就好
include "Lib/Tencent/Tencent.php";
$wx = new Tencent("Wechat");
$ret = $wx->QRcode();
?>
<!--直接生成QR码、记得把uuid给带上-->
<img id="wx" src="data:text/html;base64,<?=$ret[&#39;qrcode&#39;]?>" uuid="<?=$ret[&#39;uuid&#39;]?>">
  
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
    // setTimeout(function () {
    //     var uuid = document.getElementById(&#39;wx&#39;).getAttribute("uuid");
    //     var url ="/ajax.php?uuid="+uuid;
    //     console.log(url);
    // },1000);
    //每秒去查询一次二维码状态
    $(document).ready(function () {
        setInterval(function () {
            var uuid = document.getElementById(&#39;wx&#39;).getAttribute("uuid");
            var url ="/ajax.php?uuid="+uuid;
            $.ajax({type:"GET",url:url,success:function (data) {
                    if (data.code == 200)
                    {
                        alert("登陆成功,uin为:"+data.uid);
                    }
                }});
        },1000);
    });
  
</script>

  ajax.php :

<?php
include "Lib/Tencent/Tencent.php";
$wx = new Tencent("Wechat");
//直接获取到uuid后,监听就好了
$ret = $wx->ListenQR($_GET[&#39;uuid&#39;]);
//var_dump($ret);
echo json_encode($ret,true);exit;

  这个例子是微信的,QQ同样的代码一样可以运行

数据库用户表多一个qq和wxuin字段、用于保存用户绑定的QQ和微信

上面那个仅仅只是个例子,可能写的不是很好。大佬勿喷

推荐学习:《PHP视频教程

以上是PHP怎么实现扫码登录QQ的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn