From 01247881b289336de272e4f46c484fd2c8095317 Mon Sep 17 00:00:00 2001 From: hgc Date: Mon, 30 Dec 2024 11:20:39 +0800 Subject: [PATCH] =?UTF-8?q?grpc=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/OAuthController.php | 24 ++++ app/middleware/Jwt.php | 74 +++++++++++ app/rpc/client/AuthRpcClient.php | 86 +++++++++++++ composer.json | 3 +- composer.lock | 118 ++---------------- config/middleware.php | 1 + .../plugin/tinywan/exception-handler/app.php | 59 --------- config/plugin/tinywan/rpc/app.php | 9 -- config/plugin/tinywan/rpc/process.php | 9 -- config/route.php | 4 +- config/rpc.php | 9 ++ 11 files changed, 206 insertions(+), 190 deletions(-) create mode 100644 app/middleware/Jwt.php create mode 100644 app/rpc/client/AuthRpcClient.php delete mode 100644 config/plugin/tinywan/exception-handler/app.php delete mode 100644 config/plugin/tinywan/rpc/app.php delete mode 100644 config/plugin/tinywan/rpc/process.php create mode 100644 config/rpc.php diff --git a/app/controller/OAuthController.php b/app/controller/OAuthController.php index f3a1a23..f355929 100644 --- a/app/controller/OAuthController.php +++ b/app/controller/OAuthController.php @@ -112,6 +112,30 @@ class OAuthController public function testRefreshToken(Request $request) { + // 接建立socket连到内部推送端口 + $client = stream_socket_client('tcp://192.168.21.27:22101', $errorCode, $errorMessage); + if (false === $client) { + throw new \Exception('rpc failed to connect: '.$errorMessage); + } + $rpc_request = [ + 'class' => 'Auth', + 'method' => 'ValidateJwtToken', + 'args' => [ + [ + 'uid' => 2023, + 'username' => 'Tinywan', + ] + ] + ]; + // 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符 + fwrite($client, json_encode($rpc_request)."\n"); + // 读取推送结果 + $result = fgets($client, 10240000); + // 解析JSON字符串 + $result = json_decode($result, true); + dump($result); + return $this->successResponse($result); + //发布事件 // $dayBeforeYesterdayStart = date('Y-m-d', strtotime('-2 day')); // dump($dayBeforeYesterdayStart . '更新' . GoogleAdsDateDatas::type . '开始'); diff --git a/app/middleware/Jwt.php b/app/middleware/Jwt.php new file mode 100644 index 0000000..db5903e --- /dev/null +++ b/app/middleware/Jwt.php @@ -0,0 +1,74 @@ +header('Authorization', ''); + if (empty($authorization) || strpos($authorization, 'Bearer ') !== 0) { + return response(['code' => 1, 'msg' => '缺少 Authorization 头或格式无效'], 200); + } + + // 提取 JWT token + $jwtToken = substr($authorization, 7); + // dump($jwtToken); + // return Json([ + // 'code' => 0, + // 'msg' => 'ok', + // 'data' => $jwtToken, + // ]); + + try { + // 调用 AuthRpcClient 进行 JWT 验证 +// $authRpcClient = new AuthRpcClient(); +// $response = $authRpcClient->validateJwtToken($jwtToken); +// +// // 如果验证不通过,返回错误消息 +// if ($response['result'] !== 'JWT_VERIFY_OK') { +// return response([ +// 'code' => 1, +// 'msg' => $this->getErrorMessage($response['result']), +// ], 200); +// } +// +// // 如果验证通过,将用户数据 (claims) 存入请求属性,供后续使用 +// $request = $request->withAttribute('user', $response['claims']); +// +// // 如果返回了新 token,将其添加到响应头 X-New-Token 中 + $response = $handler($request); +// if (!empty($response['new_token'])) { +// $response = $response->withHeader('X-New-Token', $response['new_token']); +// } + + return $response; + } catch (Exception $e) { + return response(['code' => 1, 'msg' => 'JWT 验证失败: ' . $e->getMessage()], 200); + } + } + + private function getErrorMessage($result) + { + switch ($result) { + case 'JWT_VERIFY_BAD_FORMAT': + return '无效的 token 格式'; + case 'JWT_VERIFY_SIGN_FAILED': + return 'token 签名无效'; + case 'JWT_VERIFY_EXPIRED': + return 'token 已过期'; + case 'JWT_VERIFY_REVOKED': + return 'token 已被撤销'; + case 'JWT_VERSION_LOW': + return 'token 版本过低'; + default: + return '未知错误'; + } + } +} \ No newline at end of file diff --git a/app/rpc/client/AuthRpcClient.php b/app/rpc/client/AuthRpcClient.php new file mode 100644 index 0000000..72ff133 --- /dev/null +++ b/app/rpc/client/AuthRpcClient.php @@ -0,0 +1,86 @@ +host = $host ?: Config::get('rpc.auth_host', '192.168.21.27'); +// $this->port = $port ?: Config::get('rpc.auth_port', 22101); +//// dump($this->host);dump($this->port); +// // 连接到 Auth RPC 服务 +// $this->client = stream_socket_client("tcp://{$this->host}:{$this->port}", $errorCode, $errorMessage); +// dump($this->client); +// if (false === $this->client) { +// throw new Exception("RPC 连接失败: {$errorMessage}"); +// } + } + + /** + * 验证 JWT token + * + * @param string $jwtToken + * @return array + * @throws Exception + */ + public function validateJwtToken(string $jwtToken): array + { + // 从配置文件中获取 RPC 服务的连接信息 + $host = config('rpc.auth_host', '192.168.21.27'); + $port = config('rpc.auth_port', 22101); +// dump($host);dump($port); return []; + // 创建连接到 Auth RPC 服务 + $client = stream_socket_client("tcp://{$host}:{$port}", $errorCode, $errorMessage); + + if (false === $client) { + throw new Exception("RPC 连接失败: {$errorMessage}"); + } + + $rpcRequest = [ + 'class' => 'Auth', + 'method' => 'ValidateJwtToken', + 'args' => [ + ['jwt_token' => $jwtToken], + ], + ]; +// dump($rpcRequest);return []; + + // 发送请求,Text 协议需要在末尾添加换行符 + fwrite($this->client, json_encode($rpcRequest) . "\n"); + + // 读取响应 + $result = fgets($this->client, 10240000); + if (!$result) { + throw new Exception('没有收到来自 Auth RPC 服务的响应'); + } + + // 解码 JSON 响应 + $response = json_decode($result, true); + + return $response; + } + + /** + * 关闭与 RPC 服务的连接 + */ + public function close() + { + if ($this->client) { + fclose($this->client); + } + } +} diff --git a/composer.json b/composer.json index 3c750c6..7510a46 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,8 @@ "symfony/var-dumper": "^6.4", "webman/think-orm": "^1.1", "phpoffice/phpspreadsheet": "^3.6", - "tinywan/rpc": "^1.3" + "grpc/grpc": "^1.38", + "google/protobuf": "^4.29" }, "suggest": { "ext-event": "For better performance. " diff --git a/composer.lock b/composer.lock index 32d4f52..735d2dc 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": "55aa2739027c5188b7b150b785715692", + "content-hash": "3b7d410388f353ce39d707fa20dd1931", "packages": [ { "name": "brick/math", @@ -756,16 +756,16 @@ }, { "name": "google/protobuf", - "version": "v4.29.1", + "version": "v4.29.2", "source": { "type": "git", "url": "https://github.com/protocolbuffers/protobuf-php.git", - "reference": "6042b5483f8029e42473faeb8ef75ba266278381" + "reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/6042b5483f8029e42473faeb8ef75ba266278381", - "reference": "6042b5483f8029e42473faeb8ef75ba266278381", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/79aa5014efeeec3d137df5cdb0ae2fc163953945", + "reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945", "shasum": "" }, "require": { @@ -794,9 +794,9 @@ "proto" ], "support": { - "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.1" + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.2" }, - "time": "2024-12-03T22:07:45+00:00" + "time": "2024-12-18T14:11:12+00:00" }, { "name": "googleads/google-ads-php", @@ -3663,107 +3663,6 @@ ], "time": "2024-11-08T15:28:48+00:00" }, - { - "name": "tinywan/exception-handler", - "version": "v1.5.4", - "source": { - "type": "git", - "url": "https://github.com/Tinywan/webman-exception.git", - "reference": "19b58b0e3c6927fa0726c0896364275329ab52d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Tinywan/webman-exception/zipball/19b58b0e3c6927fa0726c0896364275329ab52d5", - "reference": "19b58b0e3c6927fa0726c0896364275329ab52d5", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": ">=7.4", - "workerman/webman-framework": "^1.5" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.6", - "phpstan/phpstan": "^1.4", - "tinywan/jwt": "^1.2", - "tinywan/storage": "^0.2.2", - "tinywan/validate": "^1.0", - "webman/think-orm": "^1.1", - "workerman/webman": "^1.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Tinywan\\ExceptionHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "webman exception handler plugin", - "support": { - "issues": "https://github.com/Tinywan/webman-exception/issues", - "source": "https://github.com/Tinywan/webman-exception/tree/v1.5.4" - }, - "time": "2024-07-13T05:00:19+00:00" - }, - { - "name": "tinywan/rpc", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/Tinywan/webman-rpc.git", - "reference": "5bad7989a88f877a2b1579f862e7894533368d6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Tinywan/webman-rpc/zipball/5bad7989a88f877a2b1579f862e7894533368d6a", - "reference": "5bad7989a88f877a2b1579f862e7894533368d6a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": ">=7.4", - "tinywan/exception-handler": "^1.5", - "workerman/webman-framework": "^1.5" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.6", - "phpstan/phpstan": "^1.4", - "workerman/webman": "^1.0" - }, - "type": "library", - "autoload": { - "files": [ - "src/function.php" - ], - "psr-4": { - "Tinywan\\Rpc\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Tinywan", - "email": "756684177@qq.com" - } - ], - "description": "simple rpc service for webman plugin", - "keywords": [ - "plugin", - "rpc", - "webman" - ], - "support": { - "issues": "https://github.com/Tinywan/webman-rpc/issues", - "source": "https://github.com/Tinywan/webman-rpc/tree/v1.3.0" - }, - "time": "2024-08-16T06:46:51+00:00" - }, { "name": "topthink/think-helper", "version": "v3.1.10", @@ -4412,8 +4311,5 @@ "php": ">=8.1" }, "platform-dev": {}, - "platform-overrides": { - "php": "8.1.0" - }, "plugin-api-version": "2.6.0" } diff --git a/config/middleware.php b/config/middleware.php index d460f6a..17f42bd 100644 --- a/config/middleware.php +++ b/config/middleware.php @@ -18,6 +18,7 @@ return [ '' => [ // ... 这里省略其它中间件 app\middleware\Cros::class, +// app\middleware\Jwt::class, ] ]; \ No newline at end of file diff --git a/config/plugin/tinywan/exception-handler/app.php b/config/plugin/tinywan/exception-handler/app.php deleted file mode 100644 index 74a4c33..0000000 --- a/config/plugin/tinywan/exception-handler/app.php +++ /dev/null @@ -1,59 +0,0 @@ - true, - // 错误异常配置 - 'exception_handler' => [ - // 不需要记录错误日志 - 'dont_report' => [ - Tinywan\ExceptionHandler\Exception\BadRequestHttpException::class, - Tinywan\ExceptionHandler\Exception\UnauthorizedHttpException::class, - Tinywan\ExceptionHandler\Exception\ForbiddenHttpException::class, - Tinywan\ExceptionHandler\Exception\NotFoundHttpException::class, - Tinywan\ExceptionHandler\Exception\RouteNotFoundException::class, - Tinywan\ExceptionHandler\Exception\TooManyRequestsHttpException::class, - Tinywan\ExceptionHandler\Exception\ServerErrorHttpException::class, - Tinywan\Validate\Exception\ValidateException::class, - Tinywan\Jwt\Exception\JwtTokenException::class - ], - // 自定义HTTP状态码 - 'status' => [ - 'validate' => 400, // 验证器异常 - 'jwt_token' => 401, // 认证失败 - 'jwt_token_expired' => 401, // 访问令牌过期 - 'jwt_refresh_token_expired' => 402, // 刷新令牌过期 - 'server_error' => 500, // 服务器内部错误 - 'server_error_is_response' => false, // 是否响应服务器内部错误 - 'type_error' => 400, // 参数类型错误码 - 'type_error_is_response' => false, // 参数类型与预期声明的参数类型不匹配 - ], - // 自定义响应消息 - 'body' => [ - 'code' => 0, - 'msg' => '服务器内部异常', - 'data' => null - ], - // 事件,event 与 webman/event 存在冲突,event 重命名为 event_trigger - 'event_trigger' => [ - 'enable' => false, - // 钉钉机器人 - 'dingtalk' => [ - 'accessToken' => 'xxxxxxxxxxxxxxxx', - 'secret' => 'xxxxxxxxxxxxxxxx', - 'title' => '钉钉机器人异常通知', - ] - ], - /** 异常报警域名标题 */ - 'domain' => [ - 'dev' => 'dev-api.tinywan.com', // 开发环境 - 'test' => 'test-api.tinywan.com', // 测试环境 - 'pre' => 'pre-api.tinywan.com', // 预发环境 - 'prod' => 'api.tinywan.com', // 生产环境 - ], - /** 是否生产环境 。可以通过配置文件或者数据库读取返回 eg:return config('app.env') === 'prod';*/ - 'is_prod_env' => function () { - return false; - }, - ], - -]; \ No newline at end of file diff --git a/config/plugin/tinywan/rpc/app.php b/config/plugin/tinywan/rpc/app.php deleted file mode 100644 index 185bbc1..0000000 --- a/config/plugin/tinywan/rpc/app.php +++ /dev/null @@ -1,9 +0,0 @@ - true, - 'server' => [ - 'namespace'=> 'service\\', // 自定义服务命名空间 - 'listen_text_address' => 'text://0.0.0.0:9512', // 自定义Text协议地址 - ], -]; diff --git a/config/plugin/tinywan/rpc/process.php b/config/plugin/tinywan/rpc/process.php deleted file mode 100644 index 210cea2..0000000 --- a/config/plugin/tinywan/rpc/process.php +++ /dev/null @@ -1,9 +0,0 @@ - [ - 'handler'=> \Tinywan\Rpc\Protocol\RpcTextProtocol::class, - 'listen' => config('plugin.tinywan.rpc.app.server.listen_text_address'), - 'count' => 10, // 根据配置文件调整 - ] -]; \ No newline at end of file diff --git a/config/route.php b/config/route.php index 0735672..647f94f 100644 --- a/config/route.php +++ b/config/route.php @@ -74,7 +74,9 @@ Route::group('/googleads', function () { Route::post('/callback', [OAuthController::class, 'handleCallback']); Route::post('/refresh_token_get', [OAuthController::class, 'getRefreshToken']); Route::post('/refresh_token_use', [OAuthController::class, 'useRefreshToken']); - Route::post('/refresh_token_test', [OAuthController::class, 'testRefreshToken']); + Route::post('/refresh_token_test', [OAuthController::class, 'testRefreshToken'])->middleware([ + app\middleware\Jwt::class, + ]); Route::post('/refresh_token_revoke', [OAuthController::class, 'revokeRefreshToken']); }); }); diff --git a/config/rpc.php b/config/rpc.php new file mode 100644 index 0000000..2b08e44 --- /dev/null +++ b/config/rpc.php @@ -0,0 +1,9 @@ + [ + 'host' => '192.168.21.27', + 'port' => 22101, + ] +];