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

  1. <?php
  2. class QQ extends Curl_Api
  3. {
  4. //获取登录验证码
  5. public function QRcode()
  6. {
  7. $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';
  8. $arr=$this->get_curl_split($url);
  9. preg_match('/qrsig=(.*?);/',$arr['header'],$match);
  10. if($qrsig=$match[1])
  11. return array('code'=>200,'qrsig'=>$qrsig,'data'=>base64_encode($arr['body']));
  12. else
  13. return array('code'=>400,'msg'=>'二维码获取失败');
  14. }
  15. public function ListenQR($qrsig)
  16. {
  17. $qrsig = $qrsig[0];
  18. if(empty($qrsig))return array('code'=>-1,'msg'=>'qrsig不能为空');
  19. $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&';
  20. $ret = $this->get_curl($url,0,$url,'qrsig='.$qrsig.'; ',1);
  21. if(preg_match("/ptuiCB\('(.*?)'\)/", $ret, $arr)){
  22. $r=explode("','",str_replace("', '","','",$arr[1]));
  23. if($r[0]==0){
  24. preg_match('/uin=(\d+)&/',$ret,$uin);
  25. $uin=$uin[1];
  26. preg_match('/skey=@(.{9});/',$ret,$skey);
  27. preg_match('/superkey=(.*?);/',$ret,$superkey);
  28. $data=$this->get_curl($r[2],0,0,0,1);
  29. if($data) {
  30. preg_match("/p_skey=(.*?);/", $data, $matchs);
  31. $pskey = $matchs[1];
  32. }
  33. if($pskey){
  34. if(isset($_GET['findpwd'])){
  35. $_SESSION['findpwd_qq']=$uin;
  36. }
  37. return array('code'=>200,'uin'=>$uin,'skey'=>'@'.$skey[1],'pskey'=>$pskey,'superkey'=>$superkey[1],'nick'=>$r[5]);
  38. }else{
  39. return array('code'=>201,'msg'=>'登录成功,获取相关信息失败!'.$r[2]);
  40. }
  41. }elseif($r[0]==65){
  42. return array('code'=>400,'msg'=>'二维码已失效。');
  43. }elseif($r[0]==66){
  44. return array('code'=>202,'msg'=>'二维码未失效。');
  45. }elseif($r[0]==67){
  46. return array('code'=>302,'msg'=>'正在验证二维码。');
  47. }else{
  48. return array('code'=>401,'msg'=>$r[4]);
  49. }
  50. }else{
  51. return array('code'=>403,'msg'=>$ret);
  52. }
  53.  
  54. }
  55. private function getqrtoken($qrsig){
  56. $len = strlen($qrsig);
  57. $hash = 0;
  58. for($i = 0; $i < $len; $i++){
  59. $hash += (($hash << 5) & 2147483647) + ord($qrsig[$i]) & 2147483647;
  60. $hash &= 2147483647;
  61. }
  62. return $hash & 2147483647;
  63. }
  64. }

  微信:

  1. <?php
  2. class Wechat extends Curl_Api
  3. {
  4. //获取验证码
  5. public function QRcode()
  6. {
  7. $url = "https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&fun=new&lang=zh_CN";
  8. $uuid = $this->get_curl($url);
  9. // var_dump($uuid);
  10. $uuid = substr($uuid,strpos($uuid,'"')+1,-2);
  11. $url = "https://login.wx.qq.com/qrcode/{$uuid}?t=webwx";
  12. $qrcode = file_get_contents($url);
  13. $result = ['code'=>200,'uuid'=>$uuid,'qrcode'=>base64_encode($qrcode)];
  14. return $result;
  15. }
  16. public function ListenQR($uuid)
  17. {
  18. $paras['ctime'] = 1000;
  19. $paras['rtime'] = 1000;
  20. $paras['refer'] = 'https://wx2.qq.com/';
  21. $api = 'https://login.wx2.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=' . $uuid[0] . '&tip=0';
  22. $body = $this->curl($api, $paras);
  23. preg_match('/(\d){3}/', $body, $code);
  24. preg_match('/redirect_uri="(.*?)"/', $body, $url);
  25. if ($code[0] == '200') {
  26. $body = $this->curl($url[1]);
  27. preg_match('/<wxuin>(\d*?)<\/wxuin>/', $body, $wxuin);
  28. $ret['code'] = 200;
  29. $ret['data']['uin'] = $wxuin[1];
  30. $ret['data']['type'] = 'wx';
  31. $ret['msg'] = '登录成功';
  32. } else {
  33. $ret['code'] = 408;
  34. $ret['msg'] = '请使用手机微信扫码登录';
  35. }
  36. return $ret;
  37. }
  38. }

  为了方便跳用,这里我又封装了一个类
动态传入QQ微信的类名字符串快速实例化
Tencent类:

  1. <?php
  2. Class Tencent{
  3. protected $path = __DIR__ . '/';
  4. private $cl;
  5. /*
  6. * 动态传入QQ或WX字符串,自动转换对应的api类登录
  7. */
  8. public function __construct($type)
  9. {
  10. //注册自动加载函数
  11. spl_autoload_register([$this,'Psr4Autoload']);
  12. //引入curl
  13. $this->cl = new $type();
  14. }
  15. public function Psr4Autoload($class)
  16. {
  17. $class_file = $this->path .'/'. $class . '.php';
  18. if (file_exists($class_file))
  19. {
  20. include "$class_file";
  21. }else{
  22. die('类文件'.$class_file .'不存在');
  23. }
  24. }
  25. public function QRcode()
  26. {
  27. return call_user_func([$this->cl,__FUNCTION__]);
  28. }
  29. public function ListenQR(...$args)
  30. {
  31. return call_user_func([$this->cl,__FUNCTION__],$args);
  32. }
  33. public function __call($name, $arguments)
  34. {
  35. call_user_func_array([$this->cl,$name],(array)$arguments);
  36. }
  37. }

  以及最后一个curl类:

  1. <?php
  2. class Curl_Api
  3. {
  4. public $ua = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";
  5.  
  6. public function get_curl($url,$post=0,$referer=0,$cookie=0,$header=0,$ua=0,$nobaody=0){
  7. $ch = curl_init();
  8. curl_setopt($ch, CURLOPT_URL,$url);
  9. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  10. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  11. $httpheader[] = "Accept: application/json";
  12. $httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
  13. $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
  14. $httpheader[] = "Connection: keep-alive";
  15. curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
  16. if($post){
  17. curl_setopt($ch, CURLOPT_POST, 1);
  18. curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  19. }
  20. if($header){
  21. curl_setopt($ch, CURLOPT_HEADER, TRUE);
  22. }
  23. if($cookie){
  24. curl_setopt($ch, CURLOPT_COOKIE, $cookie);
  25. }
  26. if($referer){
  27. curl_setopt($ch, CURLOPT_REFERER, $referer);
  28. }
  29. if($ua){
  30. curl_setopt($ch, CURLOPT_USERAGENT,$ua);
  31. }else{
  32. curl_setopt($ch, CURLOPT_USERAGENT,$this->ua);
  33. }
  34. if($nobaody){
  35. curl_setopt($ch, CURLOPT_NOBODY,1);
  36.  
  37. }
  38. curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  39. curl_setopt($ch, CURLOPT_ENCODING, "gzip");
  40. curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  41. $ret = curl_exec($ch);
  42. curl_close($ch);
  43. return $ret;
  44. }
  45. function curl($url, $paras = array()) {
  46. $ch = curl_init();
  47. curl_setopt($ch, CURLOPT_URL, $url);
  48. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  49. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  50. $httpheader[] = "Accept:*/*";
  51. $httpheader[] = "Accept-Encoding:gzip,deflate,sdch";
  52. $httpheader[] = "Accept-Language:zh-CN,zh;q=0.8";
  53. $httpheader[] = "Connection:close";
  54. curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
  55. if ($paras['ctime']) { // 连接超时
  56. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $paras['ctime']);
  57. }
  58. if ($paras['rtime']) { // 读取超时
  59. curl_setopt($ch, CURLOPT_TIMEOUT_MS, $paras['rtime']);
  60. }
  61. if ($paras['post']) {
  62. curl_setopt($ch, CURLOPT_POST, 1);
  63. curl_setopt($ch, CURLOPT_POSTFIELDS, $paras['post']);
  64. }
  65. if ($paras['header']) {
  66. curl_setopt($ch, CURLOPT_HEADER, true);
  67. }
  68. if ($paras['cookie']) {
  69. curl_setopt($ch, CURLOPT_COOKIE, $paras['cookie']);
  70. }
  71. if ($paras['refer']) {
  72. if ($paras['refer'] == 1) {
  73. curl_setopt($ch, CURLOPT_REFERER, 'http://m.qzone.com/infocenter?g_f=');
  74. } else {
  75. curl_setopt($ch, CURLOPT_REFERER, $paras['refer']);
  76. }
  77. }
  78. if ($paras['ua']) {
  79. curl_setopt($ch, CURLOPT_USERAGENT, $paras['ua']);
  80. } else {
  81. 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");
  82. }
  83. if ($paras['nobody']) {
  84. curl_setopt($ch, CURLOPT_NOBODY, 1);
  85. }
  86. curl_setopt($ch, CURLOPT_ENCODING, "gzip");
  87. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  88. $ret = curl_exec($ch);
  89. curl_close($ch);
  90. return $ret;
  91. }
  92. public function get_curl_split($url){
  93. $ch = curl_init();
  94. curl_setopt($ch, CURLOPT_URL,$url);
  95. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  96. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  97. $httpheader[] = "Accept: */*";
  98. $httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
  99. $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
  100. $httpheader[] = "Connection: keep-alive";
  101. curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
  102. curl_setopt($ch, CURLOPT_HEADER, TRUE);
  103. curl_setopt($ch, CURLOPT_USERAGENT,$this->ua);
  104. curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  105. curl_setopt($ch, CURLOPT_ENCODING, "gzip");
  106. curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  107. $ret = curl_exec($ch);
  108. $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  109. $header = substr($ret, 0, $headerSize);
  110. $body = substr($ret, $headerSize);
  111. $ret=array();
  112. $ret['header']=$header;
  113. $ret['body']=$body;
  114. curl_close($ch);
  115. return $ret;
  116. }
  117. }

  大致调用的流程
1、保存四个类到文件里面
2、引入文件
3、单独写两个接口,一个生成qr码(base64),一个轮询二维码扫码状态
4、用户扫码成功后、会返回一个QQ号火微信唯一id
5、这里我只演示一个微信扫码登陆的例子

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

  1. <?php
  2. //我这里只引入了一个文件的原因是因为Wechat和QQ类不用引入、只需要把Curl_Api请求类引入进来就好,但我Tencent类内已经引入了。所以这里我只需要引入一个文件就好
  3. include "Lib/Tencent/Tencent.php";
  4. $wx = new Tencent("Wechat");
  5. $ret = $wx->QRcode();
  6. ?>
  7. <!--直接生成QR码、记得把uuid给带上-->
  8. <img id="wx" src="data:text/html;base64,<?=$ret['qrcode']?>" uuid="<?=$ret['uuid']?>">
  9.  
  10. <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
  11. <script>
  12. // setTimeout(function () {
  13. // var uuid = document.getElementById('wx').getAttribute("uuid");
  14. // var url ="/ajax.php?uuid="+uuid;
  15. // console.log(url);
  16. // },1000);
  17. //每秒去查询一次二维码状态
  18. $(document).ready(function () {
  19. setInterval(function () {
  20. var uuid = document.getElementById('wx').getAttribute("uuid");
  21. var url ="/ajax.php?uuid="+uuid;
  22. $.ajax({type:"GET",url:url,success:function (data) {
  23. if (data.code == 200)
  24. {
  25. alert("登陆成功,uin为:"+data.uid);
  26. }
  27. }});
  28. },1000);
  29. });
  30.  
  31. </script>

  ajax.php :

  1. <?php
  2. include "Lib/Tencent/Tencent.php";
  3. $wx = new Tencent("Wechat");
  4. //直接获取到uuid后,监听就好了
  5. $ret = $wx->ListenQR($_GET['uuid']);
  6. //var_dump($ret);
  7. echo json_encode($ret,true);exit;

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

    • 数据库用户表多一个qq和wxuin字段、用于保存用户绑定的QQ和微信
    • 上面那个仅仅只是个例子,可能写的不是很好。大佬勿喷
    • 有什么疑问可在帖子下方发表一下

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

  1. 移动 App 接入 QQ 登录/分享 图文教程

    移动 App 接入 QQ 登录/分享 图文教程 这里先要提两个平台,腾讯开放平台和 QQ 互联平台: (一)腾讯开放平台 官网地址:https://open.tencent.com/ 介绍:腾讯开放平 ...

  2. 手机QQ访问时,html页面在QQ中自定义预览和自定义分享

    手机QQ访问时,html页面在QQ中自定义预览和自定义分享 有一天,产品说要做个自定义预览和分享功能,于是很快在微信上实现了,可是不知道在QQ上怎么实现,查看了很多网站,最后才找到了解决方案,于是想和 ...

  3. 微信轻松接入QQ客服

    一直以来,大家都苦恼怎么实现微信公众帐号可以接入客服,也因此很多第三方接口平台也开发客服系统CRM系统,不过不是操作复杂就是成本太高.今天分享一个低成本又简便的方法,让你的公众帐号接入QQ客服.下面介 ...

  4. 怎么把微信里的文件发到QQ?

    对于如何将微信里的文件发到QQ这个问题,首先要看是在手机中操作还是在电脑上操作,针对不同的发送方式逐一介绍如下: 一.从手机微信发送文件到QQ 1.在手机微信中找到需要发送的文件打开,点击右上角竖排的 ...

  5. 第三方登陆微博、qq、微信

    源文:http://blog.csdn.net/tivonalh/article/details/60954373 假设是已经申请完成各平台开发者账号. 先来简单的,微博和QQ 微博: 引入微博JS ...

  6. 第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据O ...

  7. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

  8. [c#]asp.net开发微信公众平台(7)前6篇的整体框架demo源码

    这里给出的demo是具备整体框架的微信公众平台源码, 所谓demo就是拿过去就可以直接演示使用的东西,  当然不会具备非常详细的具体到业务层面.数据层面的东西, 每个人都可以在此基础上自由发挥,  只 ...

  9. web页面接入QQ客服的方法

    在做微信二次开发的时候或者手机版网页的时候有人想在接qq客服,下面我就分享一下具体操作: 1,准备一个QQ号,可以是企业QQ,也可以是个人QQ.登录网址:http://shang.qq.com/wid ...

随机推荐

  1. win10 安装虚拟机提示 主IP地址显示网络信息不可用

    问题:在虚拟机详情下面显示 主ip地址:网络信息不可用 解决办法: 先root用户[root@dfhf~]#cd ..[root@dfhf/]#cd /etc/sysconfig/network-sc ...

  2. 事务特性,事务的隔离级别以及spring中定义的事务传播行为

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  3. C#窗体排列方式

    2020-03-11 每日一例第3天 1.设置父窗体属性:IsMdicontainer设置成true; 2.拖入menustrip控件,修改标题栏中的text文字. 3.点击“加载子窗体”设置代码: ...

  4. C++ 判断两个圆是否有交集

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <math.h> #include <easyx.h ...

  5. mongo请求超时

    no_cursor_timeout=True参数的使用 实例: import pymongo handler = pymongo.MongoClient().db.col with handler.f ...

  6. 基于 Roslyn 实现一个简单的条件解析引擎

    基于 Roslyn 实现一个简单的条件解析引擎 Intro 最近在做一个勋章的服务,我们想定义一些勋章的获取条件,满足条件之后就给用户颁发一个勋章,定义条件的时候会定义需要哪些参数,参数的类型,获取勋 ...

  7. EPX-Studio调用Dll模块

    procedure TForm1.BitBtn1Click(Sender: TObject); var REP : IExcelPanelXDisp; modulePath:string; begin ...

  8. 用Python算带有进度条的圆周率

    import time scale=50 print("执行开始".center(scale//2,"-")) start=time.perf_counter( ...

  9. MS15-034漏洞复现、HTTP.SYS远程代码执行漏洞

    #每次命令都百度去找命令,直接弄到博客方便些: 漏洞描述: 在2015年4月安全补丁日,微软发布的众多安全更新中,修复了HTTP.sys中一处允许远程执行代码漏洞,编号为:CVE-2015-1635( ...

  10. canvas绘制流星雨特效

    源码: <!DOCTYPE html><html> <head> <meta charset="utf-8"> <meta n ...