appId = $appId ? $appId : env('JS_AppID'); $this->appSecret = $appSecret ? $appSecret : env('JS_AppSecret'); //\Log::info('appId:'.($this->appId).'appSecret:'.($this->appSecret)); } public function getSignPackage($url='',$is_force = true , $only_cache= false) { $jsapiTicket = $this->getJsApiTicket($is_force , $only_cache ); $protocol = (! empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = $url?$url:"$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $timestamp = time(); $nonceStr = $this->createNonceStr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; \Log::info($string); $signature = sha1($string); $signPackage = array( "appId" => $this->appId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } private function createNonceStr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $length; $i ++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } private function getJsApiTicket($is_force = false , $only_cache= true ) { // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例 $data = unserialize(Redis::get(($this->appId)."jsapi_ticket")); if (empty($data) || $data['expire_time'] < time()) { $accessToken = $this->getToken($is_force, $only_cache); \Log::info(($this->appId).':'.$accessToken); // 如果是企业号用以下 URL 获取 ticket $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$accessToken}"; $res = json_decode($this->httpGet($url)); $ticket = $res->ticket; if ($ticket) { $data['expire_time'] = time() + 7000; $data['jsapi_ticket'] = $ticket; Redis::setex(($this->appId)."jsapi_ticket", 7000, serialize($data)); } } else { $ticket = $data['jsapi_ticket']; } \Log::info(($this->appId).':'.'jsapi_tiket:'.$ticket); return $ticket; } private function httpGet($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_TIMEOUT, 3); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_URL, $url); $res = curl_exec($curl); curl_close($curl); return $res; } /** * 获取access token * * @param string $is_force * @return unknown|unknown|mixed|object|boolean */ public function getToken($is_force = true , $only_cache= true ) { if ($is_force == false) { $data = unserialize(Redis::get(($this->appId)."access_token")); if ($data) { if (is_array($data) && $data['expire_time'] > time()) { $access_token = $data['access_token']; return $access_token; } else if (is_string($data)) { $access_token = $data; return $access_token; } } if( $only_cache ){ // 非强制获取access_token,cache没有就直接返回false,防止获取access_token的接口在高并发下被滥用 return false; } } $appId = $this->appId; $appSecret = $this->appSecret; $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appId . '&secret=' . $appSecret; $rs1 = self::https_request($url); \Log::info(($this->appId).'get_token-'.$rs1); if ($rs1) { $rs = json_decode($rs1, true); if (is_array($rs) && $rs['access_token']) { $access_token = $rs['access_token']; $expires_in = intval($rs['expires_in'], 10); if ($expires_in <= 0) { $expires_in = 5; } else if ($expires_in >= 7200) { $expires_in = 7000; } $data = array(); $data['expire_time'] = time() + $expires_in; $data['access_token'] = $access_token; Redis::setex(($this->appId).'access_token', $expires_in, serialize($data)); return $access_token; } else { $content = "get access token error:" . $rs1; \Log::info(($this->appId).$content); } } else { $content = "get access token error:" . $rs1; \Log::info(($this->appId).$content); } return false; } /** * 抓https数据 * * @param unknown $url * @param string $data * @param string $timeout */ static function https_request($url, $data = null, $timeout = 5000) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); if (! empty($data)) { curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } if ($timeout) { curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); } curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($curl); if ($output === false) { \Log::error('Curl error: ' . curl_error($curl).". url:".$url); } curl_close($curl); return $output; } public static function getConfig($url){ $options = [ 'debug' => false, 'app_id' => env('JS_AppId'), 'secret' => env('JS_AppSecret'), //'token' => 'easywechat', // 'aes_key' => null, // 可选 'log' => [ 'level' => 'debug', 'file' => storage_path('easywechat.log'), // XXX: 绝对路径!!!! ], ]; $app = new Application($options); $js = $app->js; $js->setUrl($url); $config =$js ->Config([ 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'showOptionMenu', 'hideOptionMenu', 'hideMenuItems', 'hideAllNonBaseMenuItem' ],$debug = false, $beta = false, $json = false); return $config; } }