WechatController.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Http\Controllers\Controller;
  4. use App\Http\Requests;
  5. use Illuminate\Http\Request;
  6. use App\Libs\Classes\BLogger;
  7. use App\Libs\Classes\WxSign;
  8. use EasyWeChat\Foundation\Application;
  9. use WechatOP;
  10. use Illuminate\Support\Facades\Redis;
  11. use App\Http\Models\WechatGroupGzh;
  12. use App\Http\Controllers\Wechat\Api\WechatInnerApisController;
  13. use Doctrine\Common\Cache\PredisCache;
  14. // use Doctrine\Common\Cache\RedisCache;
  15. class WechatController extends Controller
  16. {
  17. public $wx_log_path;
  18. public $options;
  19. public $host;
  20. public $auth_host;
  21. public $third_host;
  22. public $WxSign;
  23. public $token;
  24. public $gzh_name;
  25. public $gzh_app_id;
  26. public $Redis;// redis的连接对象
  27. public $WechatApi;
  28. public $param;
  29. public $official_account;
  30. // public $wechat_group_gzh;
  31. public function __construct($gzh_app_id='') {
  32. // 方便扩展
  33. $this->param = array();
  34. $this->gzh_app_id = $gzh_app_id;
  35. $this->param['gzh_app_id'] = $this->gzh_app_id;
  36. $this->param['openid'] = '';
  37. // check公众号,不等于微信测试号
  38. if(!empty($this->gzh_app_id) && $this->gzh_app_id != 'wx570bc396a51b8ff8'){
  39. $this->wechat_group_gzh = WechatGroupGzh::get_wechat_group_gzh($this->gzh_app_id);
  40. if(!empty($this->wechat_group_gzh)) {
  41. $this->param['group_api'] = $this->wechat_group_gzh['group_api'];
  42. $this->param['group'] = $this->wechat_group_gzh['group'];
  43. }else{
  44. v('invalid gzh_app_id:'.$gzh_app_id);
  45. // json_echo('invalid gzh_app_id');
  46. }
  47. }
  48. $this->wx_log_path = '/var/www/ydy_wechat/storage/logs/easywechat.log';
  49. $this->domain = env('DOMAIN');//'aizhuishu.com';
  50. $this->auth_host = $this->host = env('ONLINE_AUTH_HOST');
  51. if(env('DEVELOP_MODE') == 'online'){
  52. $this->Redis = Redis::connection();// 默认的正式库的redis
  53. }elseif(env('DEVELOP_MODE') == 'online_test'){
  54. $this->Redis = Redis::connection();// 默认env的redis
  55. }elseif(env('DEVELOP_MODE') == 'test'){
  56. $this->Redis = Redis::connection('test_redis');// 测试库的redis
  57. }elseif(env('DEVELOP_MODE') == 'local'){
  58. $this->wx_log_path = '/Applications/MAMP/htdocs/ydy_wechat/storage/logs/easywechat.log';
  59. $this->Redis = Redis::connection('test_redis');// 测试库的redis
  60. }
  61. // v('$this->Redis');v($this->Redis);
  62. // v('develop:'.env('DEVELOP_MODE').' domain:'.$this->domain);
  63. $this->WxSign = new WxSign();
  64. $this->oauth_platform_callback_base_url = $this->auth_host.'oauth/';// 第三方授权微信回跳地址
  65. $this->token = env('WECHAT_OP_TOKEN');
  66. if(!empty($this->gzh_app_id)){
  67. // token部分的redis都用正式库的
  68. // 只在授权时刻提供,丢失后需要用户重新授权
  69. $redis_key = '[wechat_op.common.component_refresh_token.'.$this->gzh_app_id.']';
  70. $component_refresh_token = Redis::Get($redis_key);
  71. // v('redis_key:'.$redis_key.' component_refresh_token:'.$component_refresh_token);
  72. $this->options = [
  73. 'app_id' => $this->gzh_app_id,
  74. 'secret' => env('WECHAT_OP_SECRET'), // 仅适用于 单独配置公众号
  75. 'token' => env('WECHAT_OP_TOKEN'), // 仅适用于 单独配置公众号
  76. 'aes_key' => env('WECHAT_OP_AES_KEY'), // 仅适用于 单独配置公众号
  77. 'auth_type' => 'COMPONENT', // COMPONENT 开放平台授权公众号,MANUAL 单独配置公众号
  78. 'component_refresh_token' => $component_refresh_token, // 授权回调时获取的 authorizer_refresh_token,仅适用于 开放品台授权公众号
  79. 'oauth' => [
  80. 'scopes' => ['snsapi_base'], // 公众号授权用户方式 snsapi_base, snsapi_userinfo
  81. 'callback' => '/oauth_callback',
  82. ],
  83. 'cache' => [
  84. 'driver' => 'redis', // redis, filesystem, laravel
  85. 'dir' => storage_path('tmp') // 只有为filesystem时候这个目录才有效
  86. ],
  87. ];
  88. // EasyWechat\Foundation\Application 对象
  89. $this->app = WechatOP::app($this->options);
  90. $this->param['app'] = $this->app;
  91. $this->WechatApi = new WechatInnerApisController($this->param);
  92. $this->official_account = $this->WechatApi->get_official_account($this->gzh_app_id);
  93. $this->param['official_account'] = $this->official_account;
  94. $this->param['WechatApi'] = $this->WechatApi;
  95. }
  96. $this->set_init_param();
  97. v('post:');v($_POST);
  98. }
  99. // 初始化post,get变量,兼容两种
  100. public function set_init_param(){
  101. if(empty($_POST)) {
  102. $_POST = $_REQUEST;
  103. }
  104. if(empty($_REQUEST)) {
  105. $_REQUEST = $_POST;
  106. }
  107. if(isset($_POST['_url'])) {
  108. unset($_POST['_url']);
  109. }
  110. if(isset($_REQUEST['_url'])) {
  111. unset($_REQUEST['_url']);
  112. }
  113. }
  114. public function redirect_url($response_url){
  115. // v('redirect_url in:'.$response_url);
  116. header("Location:".$response_url);
  117. exit;
  118. }
  119. /**
  120. * 检查签名和时间戳
  121. * @param unknown_type $request
  122. */
  123. public function check_sign_params($request){
  124. $result = array('code'=>1,'msg'=>'','data'=>'');
  125. $timestamp = !empty($request->get('timestamp'))?$request->get('timestamp'):'';
  126. $sign = !empty($request->get('sign'))?$request->get('sign'):'';
  127. v('check_sign_params:$timestamp:'.$timestamp.' $sign:'.$sign);
  128. if(empty($timestamp) || empty($sign)){
  129. $result['code'] = 0;
  130. $result['msg'] = 'invalid param';
  131. return $result;
  132. }
  133. $timestamp = $request->get('timestamp');
  134. $sign = $request->get('sign');
  135. $now = microtime(true);
  136. $diff = $now - $timestamp;
  137. v('timestamp:'.$timestamp.' now:'.$now.' diff:'.$diff);
  138. // 时间戳8小时内
  139. if($diff > 28*3600){
  140. $result['code'] = 0;
  141. $result['msg'] = 'invalid time';
  142. return $result;
  143. }
  144. $my_sign = $this->WxSign->get_sign($request->all());
  145. v('check_sign_params sign:'.$sign.' my_sign:'.$my_sign.' info:'.json_encode($request->all()));
  146. if($sign != $my_sign){
  147. $result['code'] = 0;
  148. $result['msg'] = 'invalid sign';
  149. return $result;
  150. }
  151. return $result;
  152. }
  153. }