From 48ad2ebd1b3c30a441db34b5d7624a495ca7e723 Mon Sep 17 00:00:00 2001 From: ctexthuang Date: Sat, 13 Sep 2025 12:16:13 +0800 Subject: [PATCH] fix : jwt --- app/Controller/Admin/AdminUserController.php | 14 ++-- app/Controller/Admin/LoginController.php | 3 + .../Token/RefreshAdminTokenMiddleware.php | 65 +++++++++++++++++++ app/Service/Admin/AdminUser/UserService.php | 15 ++++- app/Service/Admin/Login/LoginService.php | 7 +- app/Service/Admin/Login/RefreshService.php | 31 ++++++++- app/Service/BaseTokenService.php | 10 +++ config/autoload/jwt.php | 2 +- request/admin.http | 6 +- 9 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 app/Middleware/Token/RefreshAdminTokenMiddleware.php diff --git a/app/Controller/Admin/AdminUserController.php b/app/Controller/Admin/AdminUserController.php index bb06e71..2c19bb0 100644 --- a/app/Controller/Admin/AdminUserController.php +++ b/app/Controller/Admin/AdminUserController.php @@ -18,15 +18,21 @@ use Hyperf\Validation\Annotation\Scene; #[Middleware(AdminTokenMiddleware::class)] class AdminUserController { + /** + * @return array + */ #[RequestMapping(path: "getInfo", methods: "GET")] - public function getInfo() + public function getInfo(): array { return (new UserService)->handle(); } - #[RequestMapping(path: "refresh", methods: "POST")] - public function refresh() + /** + * @return array + */ + #[RequestMapping(path: "logout", methods: "POST")] + public function logout(): array { - return (new UserService)->refresh(); + return (new UserService)->logout(); } } diff --git a/app/Controller/Admin/LoginController.php b/app/Controller/Admin/LoginController.php index 79ba501..159d191 100644 --- a/app/Controller/Admin/LoginController.php +++ b/app/Controller/Admin/LoginController.php @@ -6,10 +6,12 @@ namespace App\Controller\Admin; use App\Annotation\ResponseFormat; use App\Controller\AbstractController; +use App\Middleware\Token\RefreshAdminTokenMiddleware; use App\Request\Admin\LoginRequest; use App\Service\Admin\Login\LoginService; use App\Service\Admin\Login\RefreshService; use Hyperf\HttpServer\Annotation\Controller; +use Hyperf\HttpServer\Annotation\Middleware; use Hyperf\HttpServer\Annotation\RequestMapping; use Hyperf\Validation\Annotation\Scene; @@ -25,6 +27,7 @@ final class LoginController extends AbstractController } #[RequestMapping(path: "refresh", methods: "POST")] + #[Middleware(RefreshAdminTokenMiddleware::class)] public function refresh(): array { return (new RefreshService)->handle(); diff --git a/app/Middleware/Token/RefreshAdminTokenMiddleware.php b/app/Middleware/Token/RefreshAdminTokenMiddleware.php new file mode 100644 index 0000000..f9438ad --- /dev/null +++ b/app/Middleware/Token/RefreshAdminTokenMiddleware.php @@ -0,0 +1,65 @@ +checkToken->checkJwt($this->parserToken($request)); + $this->checkIssuer($this->parserToken($request)); + return $handler->handle( + value( + static function (ServerRequestPlusInterface $request, UnencryptedToken $token) { + return $request->setAttribute('token', $token); + }, + $request, + $this->getJwt()->parserRefreshToken( + $this->getToken($request) + ) + ) + ); + } + + /** + * @return JwtInterface + */ + public function getJwt(): JwtInterface + { + return $this->jwtFactory->get('admin'); + } + + /** + * @param ServerRequestInterface $request + * @return UnencryptedToken + */ + protected function parserToken(ServerRequestInterface $request): UnencryptedToken + { + return $this->getJwt()->parserRefreshToken($this->getToken($request)); + } + + /** + * @param UnencryptedToken $token + * @return void + */ + public function checkIssuer(UnencryptedToken $token): void + { + $audience = $token->claims()->get(RegisteredClaims::ISSUER); + + if ($audience !== env('APP_NAME') .'_admin') throw new ErrException('token错误',ResultCode::JWT_ERROR); + } +} diff --git a/app/Service/Admin/AdminUser/UserService.php b/app/Service/Admin/AdminUser/UserService.php index 07f68bc..8a6b63d 100644 --- a/app/Service/Admin/AdminUser/UserService.php +++ b/app/Service/Admin/AdminUser/UserService.php @@ -12,12 +12,20 @@ namespace App\Service\Admin\AdminUser; use App\Lib\Jwt\RequestScopedTokenTrait; use App\Service\Admin\BaseAdminService; +use App\Service\BaseTokenService; +use Hyperf\Di\Annotation\Inject; use Lcobucci\JWT\Token\RegisteredClaims; class UserService extends BaseAdminService { use RequestScopedTokenTrait; + /** + * @var BaseTokenService + */ + #[Inject] + protected BaseTokenService $tokenService; + public function handle(): array { var_dump($this->getToken()->claims()->all()); @@ -27,8 +35,13 @@ class UserService extends BaseAdminService return $this->adminReturn->success(); } - public function refresh(): array + /** + * @return array + */ + public function logout(): array { + $this->tokenService->setJwt('admin')->getJwt()->addBlackList($this->getToken()); + return $this->adminReturn->success(); } } \ No newline at end of file diff --git a/app/Service/Admin/Login/LoginService.php b/app/Service/Admin/Login/LoginService.php index 5a49010..d0a50f6 100644 --- a/app/Service/Admin/Login/LoginService.php +++ b/app/Service/Admin/Login/LoginService.php @@ -21,11 +21,6 @@ use Hyperf\Di\Annotation\Inject; class LoginService extends BaseAdminService { - /** - * @var string jwt场景 - */ - private string $jwt = 'admin'; - /** * @var AdminUserRepository */ @@ -54,7 +49,7 @@ class LoginService extends BaseAdminService if ($adminInfo->status == AdminUserStatusCode::DISABLE) throw new ErrException('用户已禁用'); - $jwtHandle = $this->tokenService->getJwt(); + $jwtHandle = $this->tokenService->setJwt('admin')->getJwt(); return $this->adminReturn->success('success',[ 'access_token' => $jwtHandle->builderAccessToken((string) $adminInfo->id)->toString(), diff --git a/app/Service/Admin/Login/RefreshService.php b/app/Service/Admin/Login/RefreshService.php index 6c4fa09..b074bc7 100644 --- a/app/Service/Admin/Login/RefreshService.php +++ b/app/Service/Admin/Login/RefreshService.php @@ -10,18 +10,43 @@ declare(strict_types=1); namespace App\Service\Admin\Login; +use App\Lib\Jwt\RequestScopedTokenTrait; use App\Service\Admin\BaseAdminService; +use App\Service\BaseTokenService; +use Hyperf\Di\Annotation\Inject; +use Lcobucci\JWT\Token\RegisteredClaims; use Lcobucci\JWT\UnencryptedToken; class RefreshService extends BaseAdminService { + use RequestScopedTokenTrait; + + /** + * @var BaseTokenService + */ + #[Inject] + protected BaseTokenService $tokenService; + + /** + * @return array + */ public function handle(): array { - return $this->adminReturn->success(); + return $this->adminReturn->success('success',$this->refreshToken($this->getToken())); } - public function refreshToken(UnencryptedToken $token) + /** + * @param UnencryptedToken $token + * @return array + */ + public function refreshToken(UnencryptedToken $token): array { - + $jwt = $this->tokenService->setJwt('admin')->getJwt(); + $jwt->addBlackList($token); + return [ + 'access_token' => $jwt->builderAccessToken($token->claims()->get(RegisteredClaims::ID))->toString(), + 'refresh_token' => $jwt->builderRefreshToken($token->claims()->get(RegisteredClaims::ID))->toString(), + 'expire_at' => (int) $jwt->getConfig('ttl', 0), + ]; } } \ No newline at end of file diff --git a/app/Service/BaseTokenService.php b/app/Service/BaseTokenService.php index 0c3e9d6..fd3fa1b 100644 --- a/app/Service/BaseTokenService.php +++ b/app/Service/BaseTokenService.php @@ -46,6 +46,16 @@ final class BaseTokenService implements CheckTokenInterface $this->getJwt()->hasBlackList($token) && throw new ErrException('token已过期'); } + /** + * @param string $jwt + * @return $this + */ + public function setJwt(string $jwt): self + { + $this->jwt = $jwt; + return $this; + } + /** * @param UnencryptedToken $token * @return \Closure diff --git a/config/autoload/jwt.php b/config/autoload/jwt.php index 6f06825..e0121c3 100644 --- a/config/autoload/jwt.php +++ b/config/autoload/jwt.php @@ -39,7 +39,7 @@ return [ // jwt 签名key 'key' => InMemory::base64Encoded(env('JWT_SECRET')), // token过期时间,单位为秒 - 'ttl' => (int) env('ADMIN_JWT_TTL', 1), + 'ttl' => (int) env('ADMIN_JWT_TTL', 3), // 刷新token过期时间,单位为秒 'refresh_ttl' => (int) env('ADMIN_JWT_REFRESH_TTL', 10), 'claims' => [ diff --git a/request/admin.http b/request/admin.http index 527345f..8cc36d0 100644 --- a/request/admin.http +++ b/request/admin.http @@ -17,13 +17,13 @@ Authorization: Bearer {{admin_token}} ### 登录 -POST {{host}}/admin/passport/login +POST {{host}}/admin/login/refresh Content-Type: application/x-www-form-urlencoded - -username=admin&password=123456 +Authorization: Bearer {{refresh_token}} > {% client.global.set("admin_token", response.body.data.access_token); + client.global.set("refresh_token", response.body.data.refresh_token); %}