diff --git a/app/functions.php b/app/functions.php index be8b914..31b03a0 100644 --- a/app/functions.php +++ b/app/functions.php @@ -34,4 +34,33 @@ function decrypt($data, $key) { list($encrypted_data, $iv) = explode('::', base64_decode($data), 2); return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); -} \ No newline at end of file +} + +// 生成签名 +function generateSign($params, $secretKey): string +{ + // 将参数按照键名进行字典排序 + ksort($params); + // 拼接参数和对应的值 + $signStr = ''; + foreach ($params as $key => $value) { + $signStr .= $key . '=' . $value . '&'; + } + // 拼接密钥 + $signStr .= 'key=' . $secretKey; + // 使用哈希函数计算签名,这里使用 MD5 作为示例 + return strtoupper(md5($signStr)); +} + +// 验证签名 +function verifySign($params, $secretKey, $sign): bool +{ + // 生成待验证的签名 + $generatedSign = generateSign($params, $secretKey); + // 验证签名是否一致 + if ($generatedSign === $sign) { + return true; + } else { + return false; + } +} diff --git a/app/wechat/controller/IndexController.php b/app/wechat/controller/IndexController.php index cf72516..803cdcf 100644 --- a/app/wechat/controller/IndexController.php +++ b/app/wechat/controller/IndexController.php @@ -5,7 +5,6 @@ namespace app\wechat\controller; use app\admin\model\Platform; use app\common\model\Authorizers; use app\common\service\Forward; -use app\common\service\wechat\MiniProgram; use app\common\service\wechat\OpenPlatform; use support\Request; use Tinywan\ExceptionHandler\Exception\BadRequestHttpException; @@ -52,47 +51,12 @@ class IndexController /** * 获取授权链接 * @param Request $request - * @param $url + * @param string $url * @return string */ - public function authorizer(Request $request, $url = ''): string + public function authorizer(Request $request, string $url = ''): string { $url = urldecode($url); return "点击授权"; } - - /** - * 获取token给第三方平台使用 - * @param Request $request - * @return int - * @throws BadRequestHttpException - */ - public function getToken(Request $request) - { - // 开放平台应用ID - $platformAppId = $request->input('platform_appid'); - // 被授权的应用ID - $appid = $request->input('appid'); - // 校验参数 - if (empty($platformAppId) || empty($appid)) return '参数错误'; - - $platformSetting = Platform::where('app_id', $platformAppId)->find(); - $app = new MiniProgram($platformSetting->id); - - if (empty($platformSetting->third_secret)) return '请先在wechat-mp开放平台配置外部平台解密secret'; - - // 获取 component_access_token - $component_access_token = $app->app->access_token->getToken()['component_access_token']; - - // 获取 authorizer_access_token - $authorizer_access_token = $app->getToken($appid)['authorizer_access_token']; - - $result = [ - 'platform_id' => $platformAppId, - 'app_id' => $appid, - 'component_access_token' => $component_access_token, - 'authorizer_access_token' => $authorizer_access_token - ]; - return encrypt(json_encode($result), $platformSetting->third_secret); - } } diff --git a/app/wechat/controller/OpenApiController.php b/app/wechat/controller/OpenApiController.php new file mode 100644 index 0000000..169f274 --- /dev/null +++ b/app/wechat/controller/OpenApiController.php @@ -0,0 +1,46 @@ +input('platform_appid'); + // 被授权的应用ID + $appid = $request->input('appid'); + // 校验参数 + if (empty($platformAppId) || empty($appid)) return '参数错误'; + + $platformSetting = Platform::where('app_id', $platformAppId)->find(); + $app = new MiniProgram($platformSetting->id); + + if (empty($platformSetting->third_secret)) return '请先在wechat-mp开放平台配置外部平台解密secret'; + + // 获取 component_access_token + $component_access_token = $app->app->access_token->getToken()['component_access_token']; + + // 获取 authorizer_access_token + $authorizer_access_token = $app->getToken($appid)['authorizer_access_token']; + + $result = [ + 'platform_id' => $platformAppId, + 'app_id' => $appid, + 'component_access_token' => $component_access_token, + 'authorizer_access_token' => $authorizer_access_token + ]; + return encrypt(json_encode($result), $platformSetting->third_secret); + } +} \ No newline at end of file diff --git a/app/wechat/middleware/OpenApiMiddleware.php b/app/wechat/middleware/OpenApiMiddleware.php new file mode 100644 index 0000000..c3d774e --- /dev/null +++ b/app/wechat/middleware/OpenApiMiddleware.php @@ -0,0 +1,42 @@ +get('platform_appid'); + $sign = $request->get('sign'); + $time = $request->get('time'); + + // 校验参数 + if (empty($platformAppId) || empty($sign) || empty($time)) { + return error('参数不完整,请检查 platform_appid, time, sign 参数是否齐全'); + } + + // 验证签名有效期 + if ($time < time() - 3000 || $time > time() + 3000) { + return error('签名已过期'); + } + + $platformSetting = Platform::where('app_id', $platformAppId)->find(); + if (empty($platformSetting->third_secret)) { + return error('请先在开放平台处配置外部平台解密secret'); + } + + // 验证签名 + $data = $request->get(); + unset($data['sign']); + $secret = $platformSetting->third_secret; + if (!verifySign($data, $secret, $sign)) { + return error('签名验证失败'); + } + + return $handler($request); + } +} \ No newline at end of file diff --git a/composer.lock b/composer.lock index 569b742..555a673 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "dad11a64820c7df0160bac4d2bb6934a", + "content-hash": "bdcea27b1db52d1e355aecf5ace2fc22", "packages": [ { "name": "easywechat-composer/easywechat-composer", @@ -2668,8 +2668,10 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.2", - "ext-simplexml": "*" + "php": ">=7.4", + "ext-simplexml": "*", + "ext-json": "*", + "ext-curl": "*" }, "platform-dev": [], "plugin-api-version": "2.6.0" diff --git a/config/route.php b/config/route.php index 3fc4a21..f63bca8 100644 --- a/config/route.php +++ b/config/route.php @@ -14,12 +14,14 @@ use Webman\Route; -Route::any('/wechat/getToken', [app\wechat\controller\IndexController::class, 'getToken']); // 发起微信授权 Route::any('/wechat/authorizer/{url}', [app\wechat\controller\IndexController::class, 'authorizer'])->name('wechat.authorizer'); // 微信授权事件、消息与事件通知回调 Route::any('/wechat[/{appid}]', [app\wechat\controller\IndexController::class, 'index']); - - - +// openapi +Route::group('/openapi', function () { + Route::get('/getToken', [app\wechat\controller\OpenApiController::class, 'getToken']); +})->middleware( + app\wechat\middleware\OpenApiMiddleware::class +); diff --git a/front/src/views/authorizer/authorizerList.vue b/front/src/views/authorizer/authorizerList.vue index d2cb3f5..9be079c 100644 --- a/front/src/views/authorizer/authorizerList.vue +++ b/front/src/views/authorizer/authorizerList.vue @@ -302,7 +302,7 @@ export default { }, getTokenLink(appid) { - const url = window.location.origin + '/wechat/getToken?platform_appid=' + this.currentPlatform['app_id'] + '&appid=' + appid + const url = window.location.origin + '/openapi/getToken?platform_appid=' + this.currentPlatform['app_id'] + '&appid=' + appid navigator.clipboard.writeText(url) .then(() => { Message.success('复制成功')