Compare commits

..

2 Commits

Author SHA1 Message Date
a1fdeb9148 fix : jwt
Some checks are pending
Build Docker / build (push) Waiting to run
2025-09-12 23:54:21 +08:00
68ecac2fb9 fix : jwt 2025-09-12 23:54:03 +08:00
8 changed files with 122 additions and 42 deletions

View File

@@ -8,6 +8,7 @@ use App\Annotation\ResponseFormat;
use App\Controller\AbstractController; use App\Controller\AbstractController;
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 Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping; use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene; use Hyperf\Validation\Annotation\Scene;
@@ -18,8 +19,14 @@ final class LoginController extends AbstractController
{ {
#[RequestMapping(path: "login", methods: "POST")] #[RequestMapping(path: "login", methods: "POST")]
#[Scene(scene: "login")] #[Scene(scene: "login")]
public function login(LoginRequest $request) public function login(LoginRequest $request): array
{ {
return (new LoginService)->handle(); return (new LoginService)->handle();
} }
#[RequestMapping(path: "refresh", methods: "POST")]
public function refresh(): array
{
return (new RefreshService)->handle();
}
} }

View File

@@ -4,6 +4,7 @@ namespace App\Exception;
use App\Constants\ResultCode; use App\Constants\ResultCode;
use Hyperf\Server\Exception\ServerException; use Hyperf\Server\Exception\ServerException;
use Throwable;
class ErrException extends ServerException class ErrException extends ServerException
{ {
@@ -11,4 +12,23 @@ class ErrException extends ServerException
* @var int * @var int
*/ */
protected $code = ResultCode::ERROR; protected $code = ResultCode::ERROR;
/**
* @var array
*/
protected array $data = [];
public function __construct(string $message = "", int $code = 0, array $data = [], ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
$this->data = $data;
}
/**
* @return array
*/
public function getData(): array
{
return $this->data;
}
} }

View File

@@ -49,7 +49,7 @@ abstract class BaseErrExceptionHandler extends ExceptionHandler
* @var AdminReturn|ApiReturn $returnObj * @var AdminReturn|ApiReturn $returnObj
*/ */
$returnObj = $this->container->get($returnClass); $returnObj = $this->container->get($returnClass);
$result = $returnObj->error($e->getMessage(), $e->getCode()); $result = $returnObj->error($e->getMessage(), $e->getCode(), $e?->getData() ?? []);
$this->stopPropagation(); $this->stopPropagation();
return $response->withHeader("Content-Type", "application/json") return $response->withHeader("Content-Type", "application/json")
->withStatus(200) ->withStatus(200)

View File

@@ -31,7 +31,11 @@ class JwtExceptionHandler extends BaseErrExceptionHandler
return $response; return $response;
} }
protected function modifyException(JWTException $e): Throwable /**
* @param JWTException $e
* @return ErrException
*/
protected function modifyException(JWTException $e): ErrException
{ {
// 根据不同的异常类型设置不同的code和message // 根据不同的异常类型设置不同的code和message
switch ($e->getMessage()) { switch ($e->getMessage()) {
@@ -51,7 +55,7 @@ class JwtExceptionHandler extends BaseErrExceptionHandler
$e->setCustomMessage($message); $e->setCustomMessage($message);
} }
return $e; return New ErrException($message,$code);
} }
/** /**

View File

@@ -2,6 +2,8 @@
namespace App\Lib\Jwt; namespace App\Lib\Jwt;
use App\Constants\ResultCode;
use App\Exception\ErrException;
use App\Interface\JwtInterface; use App\Interface\JwtInterface;
use Carbon\Carbon; use Carbon\Carbon;
use Hyperf\Cache\CacheManager; use Hyperf\Cache\CacheManager;
@@ -16,6 +18,7 @@ use Lcobucci\JWT\UnencryptedToken;
use Lcobucci\JWT\Validation\Constraint; use Lcobucci\JWT\Validation\Constraint;
use Lcobucci\JWT\Validation\Constraint\SignedWith; use Lcobucci\JWT\Validation\Constraint\SignedWith;
use Lcobucci\JWT\Validation\Constraint\StrictValidAt; use Lcobucci\JWT\Validation\Constraint\StrictValidAt;
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
use Psr\SimpleCache\InvalidArgumentException; use Psr\SimpleCache\InvalidArgumentException;
abstract class AbstractJwt implements JwtInterface abstract class AbstractJwt implements JwtInterface
@@ -85,7 +88,7 @@ abstract class AbstractJwt implements JwtInterface
*/ */
public function parserAccessToken(string $accessToken): UnencryptedToken public function parserAccessToken(string $accessToken): UnencryptedToken
{ {
echo 1; try {
return $this->getJwtFacade() return $this->getJwtFacade()
->parse( ->parse(
$accessToken, $accessToken,
@@ -100,6 +103,9 @@ abstract class AbstractJwt implements JwtInterface
$this->getBlackListConstraint(), $this->getBlackListConstraint(),
$this->refreshTokenConstraint $this->refreshTokenConstraint
); );
} catch (RequiredConstraintsViolated $e) {
throw new ErrException('token过期',ResultCode::JWT_EXPIRED,['err_msg' => $e->getMessage()]);
}
} }
/** /**
@@ -108,6 +114,7 @@ abstract class AbstractJwt implements JwtInterface
*/ */
public function parserRefreshToken(string $refreshToken): UnencryptedToken public function parserRefreshToken(string $refreshToken): UnencryptedToken
{ {
try {
return $this->getJwtFacade() return $this->getJwtFacade()
->parse( ->parse(
$refreshToken, $refreshToken,
@@ -122,6 +129,9 @@ abstract class AbstractJwt implements JwtInterface
$this->getBlackListConstraint(), $this->getBlackListConstraint(),
$this->accessTokenConstraint $this->accessTokenConstraint
); );
}catch (RequiredConstraintsViolated $e) {
throw new ErrException('refresh_token过期',ResultCode::JWT_EXPIRED,['err_msg' => $e->getMessage()]);
}
} }
/** /**

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Middleware\Token; namespace App\Middleware\Token;
use App\Constants\ResultCode;
use App\Exception\ErrException; use App\Exception\ErrException;
use App\Interface\JwtInterface; use App\Interface\JwtInterface;
use Lcobucci\JWT\Token\RegisteredClaims; use Lcobucci\JWT\Token\RegisteredClaims;
@@ -24,6 +25,7 @@ final class AdminTokenMiddleware extends AbstractTokenMiddleware
public function checkIssuer(UnencryptedToken $token): void public function checkIssuer(UnencryptedToken $token): void
{ {
$audience = $token->claims()->get(RegisteredClaims::ISSUER); $audience = $token->claims()->get(RegisteredClaims::ISSUER);
if ($audience === env('APP_NAME') .'_admin') throw new ErrException('token错误');
if ($audience !== env('APP_NAME') .'_admin') throw new ErrException('token错误',ResultCode::JWT_ERROR);
} }
} }

View File

@@ -0,0 +1,27 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Admin\Login;
use App\Service\Admin\BaseAdminService;
use Lcobucci\JWT\UnencryptedToken;
class RefreshService extends BaseAdminService
{
public function handle(): array
{
return $this->adminReturn->success();
}
public function refreshToken(UnencryptedToken $token)
{
}
}

View File

@@ -14,8 +14,10 @@ use App\Exception\ErrException;
use App\Interface\CheckTokenInterface; use App\Interface\CheckTokenInterface;
use App\Lib\Jwt\JwtFactory; use App\Lib\Jwt\JwtFactory;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Lcobucci\JWT\Token\RegisteredClaims;
use Lcobucci\JWT\UnencryptedToken; use Lcobucci\JWT\UnencryptedToken;
use App\Interface\JwtInterface; use App\Interface\JwtInterface;
use function Hyperf\Support\value;
final class BaseTokenService implements CheckTokenInterface final class BaseTokenService implements CheckTokenInterface
{ {
@@ -35,14 +37,6 @@ final class BaseTokenService implements CheckTokenInterface
return $this->jwtFactory->get($this->jwt); return $this->jwtFactory->get($this->jwt);
} }
/**
* @return JwtInterface
*/
public function getApiJwt(): JwtInterface
{
return $this->jwtFactory->get('api');
}
/** /**
* @param UnencryptedToken $token * @param UnencryptedToken $token
* @return void * @return void
@@ -51,4 +45,20 @@ final class BaseTokenService implements CheckTokenInterface
{ {
$this->getJwt()->hasBlackList($token) && throw new ErrException('token已过期'); $this->getJwt()->hasBlackList($token) && throw new ErrException('token已过期');
} }
/**
* @param UnencryptedToken $token
* @return \Closure
*/
public function refreshToken(UnencryptedToken $token): \Closure
{
return value(static function (JwtInterface $jwt) use ($token) {
$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),
];
}, $this->getJwt());
}
} }