PHP实现的微信公众号扫码模拟登录功能示例


Posted in PHP onMay 30, 2019

本文实例讲述了PHP实现的微信公众号扫码模拟登录功能。分享给大家供大家参考,具体如下:

PHP微信公众号扫码模拟登录功能

功能只是将:https://github.com/huanz/wechat-mp-hack 改成PHP实现罢了.
之前有个休闲豆每日晨报订阅号每天定时群发消息,去年微信突然要求一定要扫码授权才能登录,FK,然后就放弃了,前几天看到早有人使用程序扫码登录,获取token,cookie自动群发了,闲着也是闲着,就将js改成php实现了登录功能.

主要流程如下

1,先访问https://mp.weixin.qq.com/ ,模拟登录,进入二维码页面
2,带着返回的cookie下载二维码.程序后台一直while循环,等待扫描消息.
3,打开下载的二维码,微信扫码,登录成功,获取token和cookie,然后后面就可以自由发挥了.

供上代码.

class WeiSendAuto
{
  //--------------------------------------------------------LOGIN START
  private $_apis = [
    "host"     => "https://mp.weixin.qq.com",
    "login"     => "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=startlogin",
    "qrcode"    => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=getqrcode¶m=4300",
    "loginqrcode"  => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=ask&token=&lang=zh_CN&f=json&ajax=1",
    "loginask"   => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=ask&token=&lang=zh_CN&f=json&ajax=1&random=",
    "loginauth"   => "https://mp.weixin.qq.com/cgi-bin/loginauth?action=ask&token=&lang=zh_CN&f=json&ajax=1",
    "bizlogin"   => "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=login&lang=zh_CN"
  ];
  private $_redirect_url = "";
  private $_key      = "";
  private function _getCookieFile(){
    return WEI_UPLOAD_PATH."cookie_{$this->_key}.text";
  }
  private function _getSavePath(){
    return WEI_UPLOAD_PATH.$this->_qrcodeName();
  }
  private function _qrcodeName(){
    return "qrcode_{$this->_key}.png";
  }
  private function _log($msg){
    Log::record("[微信调度:".date("Y-m-d H:i:s")."] ======: {$msg}");
  }
  public function getToken(){
    return Utils::getCache("token_{$this->_key}");
  }
  public function setToken($token){
     Utils::setCache("token_{$this->_key}",$token);
  }
  public function init($options){
    if(!isset($options["key"])){
      die("Key is Null!");
    }
    $this->_key   =  $options["key"];
    if($this->getToken()){
      echo("HAS Token !");
      return;
    }else{
      //尼玛,先要获取首页!!!
      $this->fetch("https://mp.weixin.qq.com/","","text");
      $this->_log("start login!!");
      $this->start_login($options);
    }
  }
  private function start_login($options){
    $_res    = $this->_login($options["account"],$options["password"]);
    if(!$_res["status"]){
      $this->_log($_res["info"]);
      return;
    }
    //保存二维码
    $this->_saveQRcode();
    $_ask_api    =  $this->_apis["loginask"];
    $_input["refer"] =  $this->_redirect_url;
    $_index     =  1;
    while(true){
/*      if($_index>60){
        break;
      }*/
      $_res    =  $this->fetch($_ask_api.$this->getWxRandomNum(),$_input);
      $_status   =  $_res["status"];
      if($_status==1){
        if($_res["user_category"]==1){
          $_ask_api = $this->_apis["loginauth"];
        }else{
          $this->_log("Login success");
          break;
        }
      }else if($_status==4){
        $this->_log("已经扫码");
      }else if($_status==2){
        $this->_log("管理员拒绝");
        break;
      }else if($_status==3){
        $this->_log("登录超时");
        break;
      }else{
        if($_ask_api==$this->_apis["loginask"]){
          $this->_log("请打开test.jpg,用微信扫码");
        }else{
          $this->_log("等待确认");
        }
      }
      sleep(2);
      $_index++;
    }
    /*if($_index>=60){
      $this->_log("U亲,超时了");
      return;
    }*/
    $this->_log("开始验证");
    $_input["post"]   = ["lang"=>"zh_CN","f"=>"json","ajax"=>1,"random"=>$this->getWxRandomNum(),"token"=>""];
    $_input["refer"]   = $this->_redirect_url;
    $_res        = $this->fetch($this->_apis["bizlogin"],$_input);
    $this->_log(print_r($_res,true));
    if($_res["base_resp"]["ret"]!=0){
      $this->_log("error = ".$_res["base_resp"]["err_msg"]);
      return ;
    }
    $redirect_url    =  $_res["redirect_url"];//跳转路径
    if(preg_match('/token=([\d]+)/i', $redirect_url,$match)){//获取cookie
      $this->setToken($match[1]);
    }
    $this->_log("验证成功,token: ".$this->getToken());
  }
  //下载二维码
  private function _saveQRcode(){
    $_input["refer"] = $this->_redirect_url;
    $_res    = $this->fetch($this->_apis["qrcode"],$_input,"text");
    $fp     = fopen($this->_getSavePath(), "wb+") or die("open fails");
    fwrite($fp,$_res) or die("fwrite fails");
    fclose($fp);
  }
  private function _login($_username,$_password){
    $_input["post"] = array(
      'username'  => $_username,
      'pwd'    => md5($_password),
      'f'     => 'json',
      'imgcode'  => ""
    );
    $_input["refer"] = "https://mp.weixin.qq.com";
    $_res      = $this->fetch($this->_apis["login"],$_input);
    if($_res["base_resp"]["ret"]!==0){
      return Utils::error($_res["base_resp"]["err_msg"]);
    }
    $this->_redirect_url  =  "https://mp.weixin.qq.com".$_res["redirect_url"];//跳转路径
    return Utils::success("ok");
  }
  function getWxRandomNum(){
    return "0.".mt_rand(1000000000000000,9999999999999999);
  }
  /**
   * @param $url
   * @param null $_input
   * @param string $data_type
   * @return mixed
   * $_input= ["post"=>[],"refer"=>"",cookiefile='']
   */
  function fetch( $url, $_input=null, $data_type='json') {
    $ch = curl_init();
    $useragent = isset($_input['useragent']) ? $_input['useragent'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2';
    //curl_setopt( $ch, CURLOPT_HTTPHEADER, $this->_headers); //设置HTTP头字段的数组
    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
    curl_setopt( $ch, CURLOPT_POST, isset($_input['post']) );
    if( isset($_input['post']) )     curl_setopt( $ch, CURLOPT_POSTFIELDS, $_input['post'] );
    if( isset($_input['refer']) )    curl_setopt( $ch, CURLOPT_REFERER, $_input['refer'] );
    curl_setopt( $ch, CURLOPT_USERAGENT, $useragent );
    curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, ( isset($_input['timeout']) ? $_input['timeout'] : 5 ) );
    curl_setopt( $ch, CURLOPT_COOKIEJAR, ( isset($_input['cookiefile']) ? $_input['cookiefile'] : $this->_getCookieFile() ));
    curl_setopt( $ch, CURLOPT_COOKIEFILE, ( isset($_input['cookiefile']) ? $_input['cookiefile'] : $this->_getCookieFile() ));
    $result = curl_exec( $ch );
    curl_close( $ch );
    if ($data_type == 'json') {
      $result = json_decode($result,true);
    }
    return $result;
  }
  //--------------------------------------------------------LOGIN END
}

怎么调用?上码

$arr = array(
  'account'  => '***',
  'password' => '****',
  'key'    => "tmall",
);
$w       =  new WeiSendAuto();
$w->init($arr);
if(!$w->getToken()){
  die("NOT TOKEN!");
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP自动生成月历代码
Oct 09 PHP
php 生成饼图 三维饼图
Sep 28 PHP
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)
Feb 06 PHP
PHP跳转页面的几种实现方法详解
Jun 08 PHP
php实现的获取网站备案信息查询代码(360)
Sep 23 PHP
PHP将XML转数组过程详解
Nov 13 PHP
PHP中Session引起的脚本阻塞问题解决办法
Apr 08 PHP
微信公众平台之快递查询功能用法实例
Apr 14 PHP
PHP实现将textarea的值根据回车换行拆分至数组
Jun 10 PHP
php面向对象值单例模式
May 03 PHP
php生成二维码图片方法汇总
Dec 17 PHP
php中输出json对象的值(实现方法)
Mar 07 PHP
PHP使用PDO创建MySQL数据库、表及插入多条数据操作示例
May 30 #PHP
TP5(thinkPHP5框架)基于bootstrap实现的单图上传插件用法示例
May 29 #PHP
TP5(thinkPHP框架)实现后台清除缓存功能示例
May 29 #PHP
PHP微信网页授权的配置文件操作分析
May 29 #PHP
thinkPHP5框架实现多数据库连接,跨数据连接查询操作示例
May 29 #PHP
tp5(thinkPHP5框架)时间查询操作实例分析
May 29 #PHP
php fread函数使用方法总结
May 28 #PHP
You might like
《PHP编程最快明白》第三讲:php数组
2010/11/01 PHP
PHP 中检查或过滤IP地址的实现代码
2011/11/27 PHP
php获取本地图片文件并生成xml文件输出具体思路
2013/04/27 PHP
php脚本运行时的超时机制详解
2016/02/17 PHP
JavaScript 序列化对象实现代码
2009/12/18 Javascript
xml文档转换工具,附图表例子(hta)
2010/11/17 Javascript
js 遍历json返回的map内容示例代码
2013/10/29 Javascript
JavaScript两种跨域技术全面介绍
2014/04/16 Javascript
JS获得浏览器版本和操作系统版本的例子
2014/05/13 Javascript
JavaScript实现弹出子窗口并传值给父窗口
2014/12/18 Javascript
解决node-webkit 不支持html5播放mp4视频的方法
2015/03/11 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
2015/04/07 Javascript
js判断手机访问或者PC的几个例子(常用于手机跳转)
2015/12/15 Javascript
JS实现超简单的汉字转拼音功能示例
2016/12/22 Javascript
JS文件/图片从电脑里面拖拽到浏览器上传文件/图片
2017/03/08 Javascript
AngularJS动态绑定ng-options的ng-model实例代码
2017/06/21 Javascript
AngularJS点击添加样式、点击变色设置的实例代码
2017/07/27 Javascript
使用jQuery实现简单的tab框实例
2017/08/22 jQuery
javascript 面向对象实战思想分享
2017/09/07 Javascript
nodejs分离html文件里面的js和css的方法
2019/04/09 NodeJs
layer.confirm()右边按钮实现href的例子
2019/09/27 Javascript
[02:40]DOTA2英雄基础教程 炼金术士
2013/12/23 DOTA
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
2017/06/12 Python
PyCharm设置每行最大长度限制的方法
2019/01/16 Python
python [:3] 实现提取数组中的数
2019/11/27 Python
Windows下python3安装tkinter的问题及解决方法
2020/01/06 Python
pytorch的batch normalize使用详解
2020/01/15 Python
anaconda升级sklearn版本的实现方法
2021/02/22 Python
比利时香水网上商店:NOTINO
2018/03/28 全球购物
理肤泉俄罗斯官网:La Roche-Posay俄罗斯
2018/07/24 全球购物
Nike香港官网:Nike HK
2019/03/23 全球购物
小学生国庆演讲稿
2014/09/05 职场文书
2015年建筑工程工作总结
2015/05/13 职场文书
pygame面向对象的飞行小鸟实现(Flappy bird)
2021/04/01 Python
mysql left join快速转inner join的过程
2021/06/30 MySQL
用Python编写简单的gRPC服务的详细过程
2021/07/04 Python