WeChat.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. /**
  5. * 政策集锦
  6. */
  7. class WeChat extends Api
  8. {
  9. //微信授权配置信息
  10. private $wechat_config = [
  11. 'appid' => 'wxe02aa578255f9184 ',
  12. 'appsecret' => '39ec8add0b8d4ed794e9cb330a334538',
  13. ];
  14. public function __construct()
  15. {
  16. $this->wechat_config = $this->wechatConfig();
  17. }
  18. /**
  19. * 获取秘钥配置
  20. * @return [type] 数组
  21. */
  22. public function wechatConfig()
  23. {
  24. // $wechat_config = array_merge($this->wechat_config, config('wechat.oauth'));
  25. $wechat_config = $this->wechat_config;
  26. return $wechat_config;
  27. }
  28. /**
  29. * 获取openid
  30. * @return string|mixed
  31. */
  32. public function getUserAccessUserInfo($code = "")
  33. {
  34. if (empty($code)) {
  35. $baseUrl = request()->url(true);
  36. $url = $this->getSingleAuthorizeUrl($baseUrl, "123");
  37. Header("Location: $url");
  38. exit();
  39. } else {
  40. $access_token = $this->getSingleAccessToken($code);
  41. return $this->getUserInfo($access_token);
  42. }
  43. }
  44. /**
  45. * 微信授权链接
  46. * @param string $redirect_uri 要跳转的地址
  47. * @return [type] 授权链接
  48. */
  49. public function getSingleAuthorizeUrl($redirect_url = "", $state = '1')
  50. {
  51. $redirect_url = urlencode($redirect_url);
  52. return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->wechat_config['appid'] . "&redirect_uri=" . $redirect_url . "&response_type=code&scope=snsapi_userinfo&state={$state}#wechat_redirect";
  53. }
  54. /**
  55. * 获取token
  56. * @return [type] 返回token
  57. */
  58. public function getSingleAccessToken($code)
  59. {
  60. $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $this->wechat_config['appid'] . '&secret=' . $this->wechat_config['appsecret'] . '&code=' . $code . '&grant_type=client_credential';
  61. // $appid = $this->wechat_config['appid'];
  62. // $secret = "39ec8add0b8d4ed794e9cb330a334538";
  63. // echo $secret;die;
  64. // $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret";
  65. // dump($url);die;
  66. $access_token = $this->https_request($url);
  67. dump($access_token);die;
  68. return $access_token;
  69. }
  70. /**
  71. * 发送curl请求
  72. * @param $url string
  73. * @param return array|mixed
  74. */
  75. public function https_request($url)
  76. {
  77. $curl = curl_init();
  78. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  79. curl_setopt($curl, CURLOPT_URL, $url);
  80. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  81. $AjaxReturn = curl_exec($curl);
  82. dump($AjaxReturn);die;
  83. //获取access_token和openid,转换为数组
  84. $data = json_decode($AjaxReturn, true);
  85. curl_close($curl);
  86. return $data;
  87. }
  88. /**
  89. * @explain
  90. * 通过code获取用户openid以及用户的微信号信息
  91. * @return array|mixed
  92. * @remark
  93. * 获取到用户的openid之后可以判断用户是否有数据,可以直接跳过获取access_token,也可以继续获取access_token
  94. * access_token每日获取次数是有限制的,access_token有时间限制,可以存储到数据库7200s. 7200s后access_token失效
  95. **/
  96. public function getUserInfo($access_token = [])
  97. {
  98. if (!$access_token) {
  99. return [
  100. 'code' => 0,
  101. 'msg' => '微信授权失败',
  102. ];
  103. }
  104. $userinfo_url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token['access_token'] . '&openid=' . $access_token['openid'] . '&lang=zh_CN';
  105. $userinfo_json = $this->https_request($userinfo_url);
  106. //获取用户的基本信息,并将用户的唯一标识保存在session中
  107. if (!$userinfo_json) {
  108. return [
  109. 'code' => 0,
  110. 'msg' => '获取用户信息失败!',
  111. ];
  112. }
  113. return $userinfo_json;
  114. }
  115. /**
  116. * 发送HTTP请求方法
  117. * @param string $url 请求URL
  118. * @param array $params 请求参数
  119. * @param string $method 请求方法GET/POST
  120. * @return array $data 响应数据
  121. */
  122. function httpCurl($url, $params, $method = 'POST', $header = array(), $multi = false){
  123. date_default_timezone_set('PRC');
  124. $opts = array(
  125. CURLOPT_TIMEOUT => 30,
  126. CURLOPT_RETURNTRANSFER => 1,
  127. CURLOPT_SSL_VERIFYPEER => false,
  128. CURLOPT_SSL_VERIFYHOST => false,
  129. CURLOPT_HTTPHEADER => $header,
  130. CURLOPT_COOKIESESSION => true,
  131. CURLOPT_FOLLOWLOCATION => 1,
  132. CURLOPT_COOKIE =>session_name().'='.session_id(),
  133. );
  134. /* 根据请求类型设置特定参数 */
  135. switch(strtoupper($method)){
  136. case 'GET':
  137. // $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
  138. // 链接后拼接参数 & 非?
  139. $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
  140. break;
  141. case 'POST':
  142. //判断是否传输文件
  143. $params = $multi ? $params : http_build_query($params);
  144. $opts[CURLOPT_URL] = $url;
  145. $opts[CURLOPT_POST] = 1;
  146. $opts[CURLOPT_POSTFIELDS] = $params;
  147. break;
  148. default:
  149. throw new Exception('不支持的请求方式!');
  150. }
  151. /* 初始化并执行curl请求 */
  152. $ch = curl_init();
  153. curl_setopt_array($ch, $opts);
  154. $data = curl_exec($ch);
  155. $error = curl_error($ch);
  156. curl_close($ch);
  157. if($error) throw new Exception('请求发生错误:' . $error);
  158. return $data;
  159. }
  160. /**
  161. * 微信信息解密
  162. * @param string $appid 小程序id
  163. * @param string $sessionKey 小程序密钥
  164. * @param string $encryptedData 在小程序中获取的encryptedData
  165. * @param string $iv 在小程序中获取的iv
  166. * @return array 解密后的数组
  167. */
  168. function decryptData( $appid , $sessionKey, $encryptedData, $iv ){
  169. $OK = 0;
  170. $IllegalAesKey = -41001;
  171. $IllegalIv = -41002;
  172. $IllegalBuffer = -41003;
  173. $DecodeBase64Error = -41004;
  174. if (strlen($sessionKey) != 24) {
  175. return $IllegalAesKey;
  176. }
  177. $aesKey=base64_decode($sessionKey);
  178. if (strlen($iv) != 24) {
  179. return $IllegalIv;
  180. }
  181. $aesIV=base64_decode($iv);
  182. $aesCipher=base64_decode($encryptedData);
  183. $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
  184. $dataObj=json_decode( $result );
  185. if( $dataObj == NULL )
  186. {
  187. return $IllegalBuffer;
  188. }
  189. if( $dataObj->watermark->appid != $appid )
  190. {
  191. return $DecodeBase64Error;
  192. }
  193. $data = json_decode($result,true);
  194. return $data;
  195. }
  196. /**
  197. * 请求过程中因为编码原因+号变成了空格
  198. * 需要用下面的方法转换回来
  199. */
  200. function define_str_replace($data)
  201. {
  202. return str_replace(' ','+',$data);
  203. }
  204. }