1、之前的某位同事的实现,下载微信示例代码,添加至当前应用的 /vender/wx_biz_msg_crypt 目录下,再在 init() 方法中 require。如图1
<?php
namespace frontend/controllers;
use Yii;
use frontend/models/http/wx_auth/AccessToken as HttpWxAuthAccessToken;
use WXBizMsgCrypt;
use yii/filters/AccessControl;
use yii/helpers/Json;
use yii/rest/Controller;
use yii/web/NotFoundHttpException;
use yii/web/ServerErrorHttpException;
class WxMsgEventController extends Controller
{
public $redis;
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'signup'],
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
];
}
public function init()
{
parent::init();
require __DIR__ . '/../vendor/wx_biz_msg_crypt/wxBizMsgCrypt.php';
$this->redis = Yii::$app->redis;
}
}
2、在 GitHab 中搜索:微信加解密,并未发现微信官方的 Git 包,确认无法基于 Composer 安装。
3、参考 引入第三方代码(Working with Third-Party Code),使用下载的类库(Using Downloaded Libraries):https://www.yiiframework.com/doc/guide/2.0/zh-cn/tutorial-yii-integration#using-downloaded-libs。
4、参考:https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md 。例子:/Aura/Web/Response/Status。决定调整类库命名方式符合 PSR-4 标准,再使用 Yii 官方的自动加载器来自动加载这些类。将 文件名 分别重命名为与 类名 相同,且大小写保持一致。
5、编辑文件:/frontend/vendor/src/wx-biz-msg-crypt/WXBizMsgCrypt.php,声明命名空间:wx/biz/msg/crypt,include_once 全部删除,其他文件也如法炮制。
<?php
namespace wx/biz/msg/crypt;
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
/**
* 1.第三方回复加密消息给公众平台;
* 2.第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。
*/
class WXBizMsgCrypt
{
}
6、需要着重注意的是文件:PKCS7Encoder.php 中存在 2 个类,需要拆分为文件:PKCS7Encoder.php、Prpcrypt.php。文件基目录为小写字母,以中横杠连接。如图2
7、给根命名空间声明一下根路径别名,编辑应用配置文件:/frontend/config/main.php。命名空间前缀为小写字母,以正斜杠连接。
return [
'aliases' => [
'@wx/biz/msg/crypt' => '@frontend/vendor/wx-biz-msg-crypt/src',
],
]
8、之前的某位同事的实现文件,再次编辑,引用的调整,use wx/biz/msg/crypt/WXBizMsgCrypt;,再在 init() 方法中 去掉 require。
<?php
namespace frontend/controllers;
use Yii;
use frontend/models/http/wx_auth/AccessToken as HttpWxAuthAccessToken;
use wx/biz/msg/crypt/WXBizMsgCrypt;
use yii/filters/AccessControl;
use yii/helpers/Json;
use yii/rest/Controller;
use yii/web/NotFoundHttpException;
use yii/web/ServerErrorHttpException;
class WxMsgEventController extends Controller
{
public $redis;
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'signup'],
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
];
}
public function init()
{
parent::init();
$this->redis = Yii::$app->redis;
}
/**
* 获取验证票据(接收微信服务器推送)
*/
public function actionTicket()
{
//try {
$request = Yii::$app->request;
$requestRawBody = $request->getRawBody();
$requestQueryParams = $request->getQueryParams();
file_put_contents(Yii::getAlias('@runtime') . '/componentVerifyTicketQueryParams.txt', print_r($requestQueryParams, true), LOCK_EX);
file_put_contents(Yii::getAlias('@runtime') . '/componentVerifyTicketRawBody.txt', print_r($requestRawBody, true), LOCK_EX);
$appId = Yii::$app->params['wxOpen']['component']['appId'];
$appSecret = Yii::$app->params['wxOpen']['component']['appSecret'];
$token = Yii::$app->params['wxOpen']['component']['token'];
$encodingAesKey = Yii::$app->params['wxOpen']['component']['symmetricKey'];
$msg = '';
$pc = new WXBizMsgCrypt($token, $encodingAesKey, $appId);
// 解密 xml 数据
$errCode = $pc->decryptMsg($requestQueryParams['msg_signature'], $requestQueryParams['timestamp'], $requestQueryParams['nonce'], $requestRawBody, $msg);
file_put_contents(Yii::getAlias('@runtime') . '/componentVerifyTicketDecrypt.txt', print_r($errCode, true), LOCK_EX);
// 解密成功
if ($errCode == 0) {
$ticketData = $this->xmlToArray($msg);
if (isset($ticketData['ComponentVerifyTicket'])) {
$redisCommandkeyPrefix = Yii::$app->params['redisCommand']['keyPrefix'];
$componentVerifyTicketKey = $redisCommandkeyPrefix . $ticketData['AppId'] . ':component_verify_ticket';
$this->redis->set($componentVerifyTicketKey, $ticketData['ComponentVerifyTicket']);
// 获取第三方平台component_access_token
$this->getComponentAccessToken($appId, $appSecret);
}
}
file_put_contents(Yii::getAlias('@runtime') . '/componentVerifyTicketMsgXml.txt', print_r($msg, true), LOCK_EX);
/*
} catch (/Throwable $th) {
file_put_contents(Yii::getAlias('@runtime') . '/componentVerifyTicketError.txt', print_r($th->getMessage(), true), LOCK_EX);
}
*/
exit('success');
}
9、将所有文件的编码调整为:UTF-8,重新运行程序,查看解密出的数据文件:componentVerifyTicketMsgXml.txt。符合预期。如图3
<xml><AppId><![CDATA[wxd98c58b273d21bdf]]></AppId> <CreateTime>1625124291</CreateTime> <InfoType><![CDATA[component_verify_ticket]]></InfoType> <ComponentVerifyTicket><![CDATA[ticket@@@PaPM2hcjK8DPPkW_ZzbaR4DCQtirExq932-BBnxhQg19QWJtIKm3Io0TXsWMqcdv-18WnjkWSiSLNPSoXmqGSA]]></ComponentVerifyTicket> </xml>
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/250600.html
