From d884aa658e06322198cbe73faba8931992ca2aee Mon Sep 17 00:00:00 2001 From: Hankin Date: Mon, 27 Apr 2026 11:15:42 +0800 Subject: [PATCH] helper --- app/Helpers/TokenHelper.php | 91 ++++++++++++ app/Http/Controllers/Controller.php | 9 ++ app/Http/Kernel.php | 2 + app/Http/Middleware/Authenticate.php | 2 +- app/Http/Middleware/CheckAdmin.php | 53 +++++++ app/Services/UtilService.php | 2 + composer.json | 1 + composer.lock | 202 ++++++++++++++++++++++++++- routes/pay/wechat.php | 3 +- 9 files changed, 362 insertions(+), 3 deletions(-) create mode 100644 app/Helpers/TokenHelper.php create mode 100644 app/Http/Middleware/CheckAdmin.php diff --git a/app/Helpers/TokenHelper.php b/app/Helpers/TokenHelper.php new file mode 100644 index 0000000..7f6fa74 --- /dev/null +++ b/app/Helpers/TokenHelper.php @@ -0,0 +1,91 @@ + $userId, + 'iat' => $now, + 'exp' => $expires + ]; + + // 使用更简单的方式:base64 编码(避免版本兼容问题) + $encoded = base64_encode(json_encode($payload)); + + // 添加签名 + $signature = hash_hmac('sha256', $encoded, self::$secret); + + return $encoded . '.' . $signature; + } + + /** + * 验证 token + * @return array|false + */ + public static function verify($tokenString) + { + try { + $parts = explode('.', $tokenString); + if (count($parts) != 2) { + return false; + } + + list($payloadEncoded, $signature) = $parts; + + // 验证签名 + $expectedSignature = hash_hmac('sha256', $payloadEncoded, self::$secret); + if (!hash_equals($expectedSignature, $signature)) { + return false; + } + + // 解码 payload + $payload = json_decode(base64_decode($payloadEncoded), true); + if (!$payload) { + return false; + } + + // 检查是否过期 + $now = time(); + if (isset($payload['exp']) && $payload['exp'] < $now) { + return false; + } + + return [ + 'user_id' => $payload['user_id'], + 'expires_at' => $payload['exp'] + ]; + + } catch (\Exception $e) { + return false; + } + } + + /** + * 刷新 token + */ + public static function refresh($oldToken, $expiresIn = 60) + { + $payload = self::verify($oldToken); + if (!$payload) { + return false; + } + + return self::generate($payload['user_id'], $expiresIn); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index acb63cb..0c929e0 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -4,10 +4,12 @@ namespace App\Http\Controllers; use App\Facades\UtilService; use App\Facades\WechatPayService; +use App\Helpers\TokenHelper; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; +use Log; class Controller extends BaseController { @@ -25,5 +27,12 @@ class Controller extends BaseController // // $res = WechatPayService::transferBatches($trade_no1, $trade_no2, $openid, $amount, $remark); // $res = WechatPayService::mchTransfer($trade_no1, $scene_id, $openid, $amount, $remark); // dd($res); + + $token = TokenHelper::generate(123); + + Log::info($token); + + $res = TokenHelper::verify($token); + dd($res); } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 40841fd..1283bee 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -65,5 +65,7 @@ class Kernel extends HttpKernel 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'merchant' => \App\Http\Middleware\CheckMerchant::class, 'merchant_user' => \App\Http\Middleware\CheckMerchantUser::class, + 'checkAdmin' => \App\Http\Middleware\CheckAdmin::class, + ]; } diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 704089a..de3dbd4 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -14,7 +14,7 @@ class Authenticate extends Middleware */ protected function redirectTo($request) { - if (! $request->expectsJson()) { + if (!$request->expectsJson()) { return route('login'); } } diff --git a/app/Http/Middleware/CheckAdmin.php b/app/Http/Middleware/CheckAdmin.php new file mode 100644 index 0000000..9a80dbf --- /dev/null +++ b/app/Http/Middleware/CheckAdmin.php @@ -0,0 +1,53 @@ +bearerToken(); + + if (!$token) { + return response()->json(['code' => 2, 'message' => '请登录后访问.'], 200); + } + + $payload = TokenHelper::verify($token); + + if (!$payload) { + return response()->json(['code' => 2, 'message' => '请登录后访问.'], 200); + } + return $next($request); + } catch (\Exception $e) { + return $this->fail('信息有误,请重新登录', 2); + } + + } + + + //接口返回失败 + public function fail($msg, $code = 5, $path = '', $operate = '', $notice = '') + { + $result = [ + 'code' => $code, + 'path' => $path, + 'message' => $msg, + 'operate' => $operate, + 'notice' => $notice, + ]; + + return Response()->json($result); + } +} diff --git a/app/Services/UtilService.php b/app/Services/UtilService.php index c83a64b..c9adb34 100644 --- a/app/Services/UtilService.php +++ b/app/Services/UtilService.php @@ -15,4 +15,6 @@ class UtilService $mix_2 = rand(100, 999); return $dateline . $mix_1 . $mix_2; } + + } diff --git a/composer.json b/composer.json index 56c0be3..19dd001 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "laravel/framework": "^9.19", "laravel/sanctum": "^3.0", "laravel/tinker": "^2.7", + "lcobucci/jwt": "^4.3", "wechatpay/wechatpay": "^1.4" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 14d9ebe..6c8ca65 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": "9824f12aeda8b0dc6d475ee5d9fb8ba9", + "content-hash": "abd6a268741333599457876ecbc1a4b6", "packages": [ { "name": "alibabacloud/oss-v2", @@ -1650,6 +1650,153 @@ }, "time": "2024-09-23T13:32:56+00:00" }, + { + "name": "lcobucci/clock", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/clock.git", + "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/fb533e093fd61321bfcbac08b131ce805fe183d3", + "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^8.0", + "stella-maris/clock": "^0.1.4" + }, + "require-dev": { + "infection/infection": "^0.26", + "lcobucci/coding-standard": "^8.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com" + } + ], + "description": "Yet another clock abstraction", + "support": { + "issues": "https://github.com/lcobucci/clock/issues", + "source": "https://github.com/lcobucci/clock/tree/2.2.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2022-04-19T19:34:17+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/4d7de2fe0d51a96418c0d04004986e410e87f6b4", + "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-sodium": "*", + "lcobucci/clock": "^2.0 || ^3.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "infection/infection": "^0.21", + "lcobucci/coding-standard": "^6.0", + "mikey179/vfsstream": "^1.6.7", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/php-invoker": "^3.1", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/4.3.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2023-01-02T13:28:00+00:00" + }, { "name": "league/commonmark", "version": "2.6.0", @@ -3451,6 +3598,59 @@ }, "time": "2025-06-01T06:28:46+00:00" }, + { + "name": "stella-maris/clock", + "version": "0.1.7", + "source": { + "type": "git", + "url": "https://github.com/stella-maris-solutions/clock.git", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stella-maris-solutions/clock/zipball/fa23ce16019289a18bb3446fdecd45befcdd94f8", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.0|^8.0", + "psr/clock": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "StellaMaris\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Heigl", + "role": "Maintainer" + } + ], + "description": "A pre-release of the proposed PSR-20 Clock-Interface", + "homepage": "https://gitlab.com/stella-maris/clock", + "keywords": [ + "clock", + "datetime", + "point in time", + "psr20" + ], + "support": { + "source": "https://github.com/stella-maris-solutions/clock/tree/0.1.7" + }, + "time": "2022-11-25T16:15:06+00:00" + }, { "name": "symfony/console", "version": "v6.0.19", diff --git a/routes/pay/wechat.php b/routes/pay/wechat.php index e1ec653..5a9d793 100644 --- a/routes/pay/wechat.php +++ b/routes/pay/wechat.php @@ -4,4 +4,5 @@ use App\Http\Controllers\WechatPayController; //发起转账 Route::post('saas/mch/transfer', [WechatPayController::class, "mchTransfer"])->middleware('merchant_user'); -Route::post('saas/mch/transfer/callback', [WechatPayController::class, "mchTransferCallback"]); +Route::post('admin/mch/transfer', [WechatPayController::class, "mchTransfer"]); +Route::post('saas/mch/transfer/callback', [WechatPayController::class, "mchTransferCallback"])->middleware("checkAdmin");