fix : jwt
Some checks failed
Build Docker / build (push) Has been cancelled

This commit is contained in:
2025-09-13 12:16:13 +08:00
parent a1fdeb9148
commit 48ad2ebd1b
9 changed files with 135 additions and 18 deletions

View File

@@ -18,15 +18,21 @@ use Hyperf\Validation\Annotation\Scene;
#[Middleware(AdminTokenMiddleware::class)] #[Middleware(AdminTokenMiddleware::class)]
class AdminUserController class AdminUserController
{ {
/**
* @return array
*/
#[RequestMapping(path: "getInfo", methods: "GET")] #[RequestMapping(path: "getInfo", methods: "GET")]
public function getInfo() public function getInfo(): array
{ {
return (new UserService)->handle(); 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();
} }
} }

View File

@@ -6,10 +6,12 @@ namespace App\Controller\Admin;
use App\Annotation\ResponseFormat; use App\Annotation\ResponseFormat;
use App\Controller\AbstractController; use App\Controller\AbstractController;
use App\Middleware\Token\RefreshAdminTokenMiddleware;
use App\Request\Admin\LoginRequest; use App\Request\Admin\LoginRequest;
use App\Service\Admin\Login\LoginService; use App\Service\Admin\Login\LoginService;
use App\Service\Admin\Login\RefreshService; use App\Service\Admin\Login\RefreshService;
use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping; use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene; use Hyperf\Validation\Annotation\Scene;
@@ -25,6 +27,7 @@ final class LoginController extends AbstractController
} }
#[RequestMapping(path: "refresh", methods: "POST")] #[RequestMapping(path: "refresh", methods: "POST")]
#[Middleware(RefreshAdminTokenMiddleware::class)]
public function refresh(): array public function refresh(): array
{ {
return (new RefreshService)->handle(); return (new RefreshService)->handle();

View File

@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace App\Middleware\Token;
use App\Constants\ResultCode;
use App\Exception\ErrException;
use App\Interface\JwtInterface;
use Lcobucci\JWT\Token\RegisteredClaims;
use Lcobucci\JWT\UnencryptedToken;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Swow\Psr7\Message\ServerRequestPlusInterface;
use function Hyperf\Support\env;
use function Hyperf\Support\value;
class RefreshAdminTokenMiddleware extends AbstractTokenMiddleware
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$this->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);
}
}

View File

@@ -12,12 +12,20 @@ namespace App\Service\Admin\AdminUser;
use App\Lib\Jwt\RequestScopedTokenTrait; use App\Lib\Jwt\RequestScopedTokenTrait;
use App\Service\Admin\BaseAdminService; use App\Service\Admin\BaseAdminService;
use App\Service\BaseTokenService;
use Hyperf\Di\Annotation\Inject;
use Lcobucci\JWT\Token\RegisteredClaims; use Lcobucci\JWT\Token\RegisteredClaims;
class UserService extends BaseAdminService class UserService extends BaseAdminService
{ {
use RequestScopedTokenTrait; use RequestScopedTokenTrait;
/**
* @var BaseTokenService
*/
#[Inject]
protected BaseTokenService $tokenService;
public function handle(): array public function handle(): array
{ {
var_dump($this->getToken()->claims()->all()); var_dump($this->getToken()->claims()->all());
@@ -27,8 +35,13 @@ class UserService extends BaseAdminService
return $this->adminReturn->success(); 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(); return $this->adminReturn->success();
} }
} }

View File

@@ -21,11 +21,6 @@ use Hyperf\Di\Annotation\Inject;
class LoginService extends BaseAdminService class LoginService extends BaseAdminService
{ {
/**
* @var string jwt场景
*/
private string $jwt = 'admin';
/** /**
* @var AdminUserRepository * @var AdminUserRepository
*/ */
@@ -54,7 +49,7 @@ class LoginService extends BaseAdminService
if ($adminInfo->status == AdminUserStatusCode::DISABLE) throw new ErrException('用户已禁用'); if ($adminInfo->status == AdminUserStatusCode::DISABLE) throw new ErrException('用户已禁用');
$jwtHandle = $this->tokenService->getJwt(); $jwtHandle = $this->tokenService->setJwt('admin')->getJwt();
return $this->adminReturn->success('success',[ return $this->adminReturn->success('success',[
'access_token' => $jwtHandle->builderAccessToken((string) $adminInfo->id)->toString(), 'access_token' => $jwtHandle->builderAccessToken((string) $adminInfo->id)->toString(),

View File

@@ -10,18 +10,43 @@ declare(strict_types=1);
namespace App\Service\Admin\Login; namespace App\Service\Admin\Login;
use App\Lib\Jwt\RequestScopedTokenTrait;
use App\Service\Admin\BaseAdminService; use App\Service\Admin\BaseAdminService;
use App\Service\BaseTokenService;
use Hyperf\Di\Annotation\Inject;
use Lcobucci\JWT\Token\RegisteredClaims;
use Lcobucci\JWT\UnencryptedToken; use Lcobucci\JWT\UnencryptedToken;
class RefreshService extends BaseAdminService class RefreshService extends BaseAdminService
{ {
use RequestScopedTokenTrait;
/**
* @var BaseTokenService
*/
#[Inject]
protected BaseTokenService $tokenService;
/**
* @return array
*/
public function handle(): 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<string,int|string>
*/
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),
];
} }
} }

View File

@@ -46,6 +46,16 @@ final class BaseTokenService implements CheckTokenInterface
$this->getJwt()->hasBlackList($token) && throw new ErrException('token已过期'); $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 * @param UnencryptedToken $token
* @return \Closure * @return \Closure

View File

@@ -39,7 +39,7 @@ return [
// jwt 签名key // jwt 签名key
'key' => InMemory::base64Encoded(env('JWT_SECRET')), 'key' => InMemory::base64Encoded(env('JWT_SECRET')),
// token过期时间单位为秒 // token过期时间单位为秒
'ttl' => (int) env('ADMIN_JWT_TTL', 1), 'ttl' => (int) env('ADMIN_JWT_TTL', 3),
// 刷新token过期时间单位为秒 // 刷新token过期时间单位为秒
'refresh_ttl' => (int) env('ADMIN_JWT_REFRESH_TTL', 10), 'refresh_ttl' => (int) env('ADMIN_JWT_REFRESH_TTL', 10),
'claims' => [ 'claims' => [

View File

@@ -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 Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{refresh_token}}
username=admin&password=123456
> {% > {%
client.global.set("admin_token", response.body.data.access_token); client.global.set("admin_token", response.body.data.access_token);
client.global.set("refresh_token", response.body.data.refresh_token);
%} %}