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