WechatCheck.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace App\Http\Middleware;
  3. use App\Services\Common\CurlService;
  4. use App\Wechat\WechatParam;
  5. use Closure;
  6. use Illuminate\Support\Facades\Cache;
  7. use Illuminate\Support\Facades\Log;
  8. /**
  9. * 公众号检查,获取支付openid
  10. * Class OfficialCheck
  11. * @package App\Http\Middleware
  12. * Auth Zhong
  13. * Date 2019/2/22
  14. */
  15. class WechatCheck
  16. {
  17. /**
  18. * OfficialCheck constructor.
  19. */
  20. public function __construct()
  21. {
  22. }
  23. /**
  24. * Handle an incoming request.
  25. *
  26. * @param \Illuminate\Http\Request $request
  27. * @param \Closure $next
  28. * @return mixed
  29. */
  30. public function handle($request, Closure $next)
  31. {
  32. //获取jsapi_ticket
  33. $jsapi_ticket = Cache::get('wechat_jsapi_ticket');
  34. if (empty($jsapi_ticket)) {
  35. $jsapi_ticket = $this->_getJsApiTicket();
  36. if (empty($jsapi_ticket)) {
  37. return $next($request);
  38. }
  39. }
  40. //生成配置
  41. $timestamp = time();
  42. $noncestr = $this->_generateNonceStr();
  43. $url = $request->getUri();
  44. $ret = strpos($url, '#');
  45. if ($ret) {
  46. $url = substr($url, 0, $ret);
  47. }
  48. $url = trim($url);
  49. if (empty($url))
  50. return $next($request);
  51. $arrdata = ["timestamp" => $timestamp, "noncestr" => $noncestr, "url" => $url, "jsapi_ticket" => $jsapi_ticket];
  52. $sign = $this->_getSignature($arrdata);
  53. if (!$sign)
  54. return $next($request);
  55. WechatParam::instance()->merge([
  56. "nonceStr" => $noncestr,
  57. "timestamp" => $timestamp,
  58. "url" => $url,
  59. "signature" => $sign,
  60. ]);
  61. return $next($request);
  62. }
  63. /**
  64. * 获取jsapi_ticket
  65. */
  66. private function _getJsApiTicket()
  67. {
  68. $access_token = $this->_getAccessToken();
  69. if (empty($access_token)) {
  70. return null;
  71. }
  72. $curl = new CurlService();
  73. $res = $curl->get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $access_token . '&type=jsapi');
  74. if (!empty($res)) {
  75. if (isset($res->ticket)) {
  76. Cache::put("wechat_jsapi_ticket", $res->ticket, 100);
  77. return $res->ticket;
  78. }
  79. }
  80. return null;
  81. }
  82. /**
  83. * 获取access_token
  84. */
  85. private function _getAccessToken()
  86. {
  87. $access_token = Cache::get('wechat_access_token');
  88. if (empty($access_token)) {
  89. $curl = new CurlService();
  90. $wechat = WechatParam::instance()->getParam();
  91. $res = $curl->get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$wechat['appid']}&secret={$wechat['appsecret']}");
  92. if (!empty($res)) {
  93. // Log::info('获取token:' . json_encode($res));
  94. if (isset($res->access_token)) {
  95. Cache::put("wechat_access_token", $res->access_token, 100);
  96. return $res->access_token;
  97. }
  98. }
  99. return null;
  100. }
  101. return $access_token;
  102. }
  103. /**
  104. * 生成随机字串
  105. * @param number $length 长度,默认为16,最长为32字节
  106. * @return string
  107. */
  108. private function _generateNonceStr($length = 16)
  109. {
  110. // 密码字符集,可任意添加你需要的字符
  111. $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  112. $str = "";
  113. for ($i = 0; $i < $length; $i++) {
  114. $str .= $chars[mt_rand(0, strlen($chars) - 1)];
  115. }
  116. return $str;
  117. }
  118. /**
  119. * 获取签名
  120. * @param array $arrdata 签名数组
  121. * @param string $method 签名方法
  122. * @return boolean|string 签名值
  123. */
  124. private function _getSignature($arrdata, $method = "sha1")
  125. {
  126. if (!function_exists($method)) return false;
  127. ksort($arrdata);
  128. $paramstring = "";
  129. foreach ($arrdata as $key => $value) {
  130. if (strlen($paramstring) == 0)
  131. $paramstring .= $key . "=" . $value;
  132. else
  133. $paramstring .= "&" . $key . "=" . $value;
  134. }
  135. $Sign = $method($paramstring);
  136. return $Sign;
  137. }
  138. }