es
parent
582cf43d02
commit
5e4aa8a009
@ -1,34 +1,36 @@ |
|||||||
<?php |
<?php |
||||||
|
declare (strict_types=1); |
||||||
|
|
||||||
namespace app\api\controller; |
namespace app\api\controller; |
||||||
|
|
||||||
use cores\BaseController; |
use cores\BaseController; |
||||||
use think\facade\Db; |
|
||||||
use think\response\Json; |
use think\response\Json; |
||||||
|
|
||||||
class Wxserver extends BaseController |
class Wxserver extends BaseController |
||||||
{ |
{ |
||||||
public function index(): Json |
public function index(): Json |
||||||
{ |
{ |
||||||
return $this->renderSuccess('访问成功'); |
$obj = new \app\common\library\wxserver\Server(); |
||||||
|
$url = $this->request->domain(true) . '/api/wxserver/redirect'; |
||||||
|
$jumUrl = $obj->jumpH5Url($url); |
||||||
|
return $this->renderSuccess(compact('jumUrl')); |
||||||
} |
} |
||||||
|
|
||||||
public function verifyTicket() |
public function verifyTicket() |
||||||
{ |
{ |
||||||
$data = $this->request->post(); |
$xmlData = file_get_contents("php://input"); |
||||||
$xmlData = file_get_contents("php://input"); // 获取原始的XML数据 |
$obj = new \app\common\library\wxserver\Server(); |
||||||
Db::table('yoshop_wx_server')->insertGetId(['content' => '进来了', 'created_at' => date('Y-m-d H:i:s')]); |
$obj->getVerifyTicket($xmlData); |
||||||
// 解析XML数据 |
|
||||||
// $xml = simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA); |
|
||||||
// $fromUser = $xml->FromUserName; |
|
||||||
// $toUser = $xml->ToUserName; |
|
||||||
// $content = $xml->Content; |
|
||||||
if ($xmlData) { |
|
||||||
Db::table('yoshop_wx_server')->insertGetId(['content' => $xmlData, 'created_at' => date('Y-m-d H:i:s')]); |
|
||||||
} |
|
||||||
if ($data) { |
|
||||||
Db::table('yoshop_wx_server')->insertGetId(['content' => $data, 'created_at' => date('Y-m-d H:i:s')]); |
|
||||||
} |
|
||||||
echo 'success'; |
echo 'success'; |
||||||
} |
} |
||||||
|
|
||||||
|
public function redirect() |
||||||
|
{ |
||||||
|
$authorization_code = $this->request->param('authorization_code'); |
||||||
|
$expires_in = $this->request->param('expires_in'); |
||||||
|
if ($authorization_code) { |
||||||
|
$obj = new \app\common\library\wxserver\Server(); |
||||||
|
$obj->authorizationInfo($authorization_code); |
||||||
|
} |
||||||
|
} |
||||||
} |
} |
@ -0,0 +1,188 @@ |
|||||||
|
<?php |
||||||
|
declare (strict_types=1); |
||||||
|
|
||||||
|
namespace app\common\library\wxserver; |
||||||
|
|
||||||
|
use app\common\model\WxserverAccount; |
||||||
|
use think\facade\Cache; |
||||||
|
use think\facade\Db; |
||||||
|
|
||||||
|
class Server |
||||||
|
{ |
||||||
|
const APPID = 'wxc03d95d3597e348a '; |
||||||
|
const SECRET = 'e2720e31673906be6e92afd377b927ba'; |
||||||
|
const TOKEN = 'obUzmSA4MvMjOblZ5NCpgecTZYaGtAg6';//消息校验Token |
||||||
|
const KEY = '2tujZuThOCzcuoBcBmeqMPjL6phcsv2dY7pgwYJwdtX'; //消息加解密Key |
||||||
|
protected WxBizMsgCrypt $crypt; |
||||||
|
|
||||||
|
public function __construct() |
||||||
|
{ |
||||||
|
$this->crypt = new WxBizMsgCrypt(self::TOKEN, self::KEY, self::APPID); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @notes:保存Ticket |
||||||
|
* @param string $xml |
||||||
|
* @return mixed|string |
||||||
|
* @author: wanghousheng |
||||||
|
*/ |
||||||
|
public function getVerifyTicket(string $xml) |
||||||
|
{ |
||||||
|
$ticket = ''; |
||||||
|
$xmlData = $this->crypt->fromXml($xml); |
||||||
|
if (!empty($xmlData['Encrypt'])) { |
||||||
|
//解密 |
||||||
|
$encryptXml = $this->crypt->decryptMsg($xmlData['Encrypt']); |
||||||
|
$data = $this->crypt->fromXml($encryptXml); |
||||||
|
if (!empty($data['ComponentVerifyTicket'])) { |
||||||
|
$ticket = $data['ComponentVerifyTicket']; |
||||||
|
Db::table('yoshop_wx_server')->insertGetId(['content' => '存入ticket成功&' . $ticket, 'created_at' => date('Y-m-d H:i:s')]); |
||||||
|
Cache::set('component_verify_ticket', $ticket, 3600); |
||||||
|
} |
||||||
|
} |
||||||
|
return $ticket; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @notes:获取令牌 |
||||||
|
* @return mixed|string |
||||||
|
* @author: wanghousheng |
||||||
|
*/ |
||||||
|
public function getComponentAccessToken() |
||||||
|
{ |
||||||
|
if (Cache::has('ComponentAccessToken')) { |
||||||
|
return Cache::get('ComponentAccessToken'); |
||||||
|
} |
||||||
|
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token'; |
||||||
|
$ticket = Cache::get('component_verify_ticket'); |
||||||
|
if (!empty($ticket)) { |
||||||
|
$data = []; |
||||||
|
$data['component_appid'] = self::APPID; |
||||||
|
$data['component_appsecret'] = self::SECRET; |
||||||
|
$data['component_verify_ticket'] = $ticket; |
||||||
|
$result = $this->curlPost($url, json_encode($data), 10); |
||||||
|
$result = json_decode($result, true); |
||||||
|
if (!empty($result['component_access_token'])) { |
||||||
|
$expire = !empty($result['expires_in']) ? intval($result['expires_in']) : 7200; |
||||||
|
Cache::set('ComponentAccessToken', $result['component_access_token'], $expire); |
||||||
|
return $result['component_access_token']; |
||||||
|
} |
||||||
|
} |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @notes:生成H5授权链接 |
||||||
|
* @param string $redirect_uri //授权后重定向的回调链接地址 |
||||||
|
* @param string $biz_appid //业务公众号appid |
||||||
|
* @return string |
||||||
|
* @author: wanghousheng |
||||||
|
*/ |
||||||
|
public function jumpH5Url(string $redirect_uri, string $biz_appid = ''): string |
||||||
|
{ |
||||||
|
$url = ''; |
||||||
|
$auth_code = $this->getPreAuthCode(); |
||||||
|
if ($auth_code) { |
||||||
|
$url = "'https://open.weixin.qq.com/wxaopen/safe/bindcomponent?action=bindcomponent&no_scan=1"; |
||||||
|
$url .= "&component_appid=" . self::APPID . '&pre_auth_code=' . $auth_code . '&redirect_uri=' . $redirect_uri; |
||||||
|
$url .= '&auth_type=3&biz_appid=' . $biz_appid . '#wechat_redirect'; |
||||||
|
} |
||||||
|
return $url; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @notes:获取预授权码 |
||||||
|
* @return false|mixed |
||||||
|
* @author: wanghousheng |
||||||
|
*/ |
||||||
|
public function getPreAuthCode() |
||||||
|
{ |
||||||
|
$token = $this->getComponentAccessToken(); |
||||||
|
if ($token) { |
||||||
|
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=' . $token; |
||||||
|
$data['component_appid'] = self::APPID; |
||||||
|
$result = $this->curlPost($url, json_encode($data)); |
||||||
|
$result = json_decode($result, true); |
||||||
|
if ($result && !empty($result['pre_auth_code'])) { |
||||||
|
return $result['pre_auth_code']; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @notes:获取授权信息 |
||||||
|
* @param $authorization_code |
||||||
|
* @author: wanghousheng |
||||||
|
*/ |
||||||
|
public function authorizationInfo($authorization_code) |
||||||
|
{ |
||||||
|
Db::table('yoshop_wx_server')->insertGetId(['content' => '回调进来了' . $authorization_code, 'created_at' => date('Y-m-d H:i:s')]); |
||||||
|
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=' . $this->getComponentAccessToken(); |
||||||
|
$data = []; |
||||||
|
$data['component_appid'] = self::APPID; |
||||||
|
$data['authorization_code'] = $authorization_code; |
||||||
|
$result = $this->curlPost($url, json_encode($data)); |
||||||
|
$result = json_decode($result, true); |
||||||
|
Db::table('yoshop_wx_server')->insertGetId(['content' => json_encode($result), 'created_at' => date('Y-m-d H:i:s')]); |
||||||
|
if ($result && !empty($result['authorization_info']) && !empty($result['authorization_info']['authorizer_appid'])) { |
||||||
|
Db::table('yoshop_wx_server')->insertGetId(['content' => '获取详情' . $authorization_code, 'created_at' => date('Y-m-d H:i:s')]); |
||||||
|
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=' . $this->getComponentAccessToken(); |
||||||
|
$data = []; |
||||||
|
$data['component_appid'] = self::APPID; |
||||||
|
$data['authorizer_appid'] = $result['authorization_info']['authorizer_appid']; |
||||||
|
$res = $this->curlPost($url, json_encode($data)); |
||||||
|
$res = json_decode($res, true); |
||||||
|
Db::table('yoshop_wx_server')->insertGetId(['content' => json_encode($res), 'created_at' => date('Y-m-d H:i:s')]); |
||||||
|
if ($res && !empty($res['authorizer_info']) && !empty($res['authorization_info'])) { |
||||||
|
$authorizer_info = $res['authorizer_info']; |
||||||
|
$authorization_info = $res['authorization_info']; |
||||||
|
$insert_data['appid'] = $authorization_info['authorizer_appid']; |
||||||
|
$insert_data['access_token'] = $result['authorization_info']['authorizer_access_token']; |
||||||
|
$insert_data['refresh_token'] = $authorization_info['authorizer_refresh_token']; |
||||||
|
$insert_data['nick_name'] = $authorizer_info['nick_name']; |
||||||
|
$insert_data['head_image'] = $authorizer_info['head_img']; |
||||||
|
$insert_data['user_name'] = $authorizer_info['user_name']; |
||||||
|
$insert_data['qrcode_image'] = $authorizer_info['qrcode_url']; |
||||||
|
$insert_data['principal_name'] = $authorizer_info['principal_name']; |
||||||
|
$insert_data['signature'] = $authorizer_info['signature']; |
||||||
|
$model = new WxserverAccount(); |
||||||
|
$model->insertGetId($insert_data); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function curlPost($url, $post_data, $timeout = 5) |
||||||
|
{ |
||||||
|
$ch = curl_init(); |
||||||
|
if (stripos($url, 'https://') !== false) { |
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); |
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); |
||||||
|
curl_setopt($ch, CURLOPT_SSLVERSION, 1); |
||||||
|
} |
||||||
|
if (is_string($post_data)) { |
||||||
|
$strPOST = $post_data; |
||||||
|
} else { |
||||||
|
$aPOST = array(); |
||||||
|
foreach ($post_data as $key => $val) { |
||||||
|
$aPOST[] = $key . '=' . urlencode($val); |
||||||
|
} |
||||||
|
$strPOST = join('&', $aPOST); |
||||||
|
} |
||||||
|
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1); |
||||||
|
curl_setopt($ch, CURLOPT_URL, $url); |
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
||||||
|
curl_setopt($ch, CURLOPT_POST, true); |
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $strPOST); |
||||||
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); |
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); |
||||||
|
$result = curl_exec($ch); |
||||||
|
$aStatus = curl_getinfo($ch); |
||||||
|
curl_close($ch); |
||||||
|
if (intval($aStatus['http_code']) == 200) { |
||||||
|
return $result; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
<?php |
||||||
|
declare (strict_types=1); |
||||||
|
|
||||||
|
namespace app\common\library\wxserver; |
||||||
|
|
||||||
|
class WxBizMsgCrypt |
||||||
|
{ |
||||||
|
private string $appId; |
||||||
|
private string $token; |
||||||
|
|
||||||
|
private string $encodingAesKey; |
||||||
|
|
||||||
|
public function __construct(string $token, string $encodingAesKey, string $appId) |
||||||
|
{ |
||||||
|
$this->token = $token; |
||||||
|
$this->encodingAesKey = $encodingAesKey; |
||||||
|
$this->appId = $appId; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @notes:xml转数组 |
||||||
|
* @param $xml |
||||||
|
* @return mixed |
||||||
|
* @author: wanghousheng |
||||||
|
*/ |
||||||
|
public function fromXml($xml) |
||||||
|
{ |
||||||
|
// 禁止引用外部xml实体 |
||||||
|
libxml_disable_entity_loader(); |
||||||
|
return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @notes: 解密 |
||||||
|
* @param $msg_encrypt |
||||||
|
* @return false|string |
||||||
|
* @author: wanghousheng |
||||||
|
*/ |
||||||
|
public function decryptMsg($msg_encrypt) |
||||||
|
{ |
||||||
|
$EncodingAESKey = $this->encodingAesKey; |
||||||
|
$AESKey = base64_decode($EncodingAESKey . '='); |
||||||
|
$iv = substr($AESKey, 0, 16); |
||||||
|
$msg_decode = base64_decode($msg_encrypt); |
||||||
|
$msg = openssl_decrypt($msg_decode, 'AES-256-CBC', $AESKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); |
||||||
|
$msg_len = unpack('N', substr($msg, 16, 4)); |
||||||
|
$len = $msg_len[1]; |
||||||
|
return substr($msg, 20, $len); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace app\common\model; |
||||||
|
|
||||||
|
use cores\BaseModel; |
||||||
|
|
||||||
|
class WxserverAccount extends BaseModel |
||||||
|
{ |
||||||
|
// 定义表名 |
||||||
|
protected $name = 'wxserver_account'; |
||||||
|
|
||||||
|
// 定义主键 |
||||||
|
protected $pk = 'id'; |
||||||
|
} |
Loading…
Reference in new issue