|
|
@ -1,11 +1,12 @@ |
|
|
<?php |
|
|
<?php |
|
|
namespace app\api\service; |
|
|
namespace app\api\service; |
|
|
|
|
|
|
|
|
use Lcobucci\JWT\Parser; |
|
|
|
|
|
use Lcobucci\JWT\Builder; |
|
|
use Lcobucci\JWT\Builder; |
|
|
use Lcobucci\JWT\Signer\Hmac\Sha256; |
|
|
use Lcobucci\JWT\Signer\Hmac\Sha256; |
|
|
use Lcobucci\JWT\Signer\Key\InMemory; |
|
|
use Lcobucci\JWT\Signer\Key\InMemory; |
|
|
use Lcobucci\JWT\Token; |
|
|
use Lcobucci\JWT\Token; |
|
|
|
|
|
use DateTimeImmutable; |
|
|
|
|
|
|
|
|
class JWTService |
|
|
class JWTService |
|
|
{ |
|
|
{ |
|
|
@ -21,20 +22,26 @@ class JWTService |
|
|
$signer = new Sha256(); |
|
|
$signer = new Sha256(); |
|
|
$key = InMemory::plainText($this->secret); |
|
|
$key = InMemory::plainText($this->secret); |
|
|
|
|
|
|
|
|
|
|
|
$now = new DateTimeImmutable(); // 当前时间 |
|
|
|
|
|
|
|
|
$builder = new Builder(); |
|
|
$builder = new Builder(); |
|
|
|
|
|
|
|
|
// 设置发行时间和过期时间 |
|
|
// 设置发行时间和过期时间 |
|
|
$now = time(); |
|
|
$secondsToAdd = (int) config('jwt.token_ttl'); |
|
|
|
|
|
$expiresAt = $now->add(new \DateInterval('PT' . $secondsToAdd . 'S')); |
|
|
|
|
|
|
|
|
$token = $builder |
|
|
$token = $builder |
|
|
->issuedAt($now) // iat: 发行时间 |
|
|
->issuedAt($now) // iat: 发行时间 |
|
|
->expiresAt($now + config('jwt.token_ttl')) // exp: 过期时间 |
|
|
->expiresAt($expiresAt) // exp: 过期时间 |
|
|
->withClaim('iss', 'your_issuer') // iss: 发行人 |
|
|
|
|
|
->withClaim('sub', 'your_subject') // sub: 主题 |
|
|
// 使用专用方法设置注册声明 |
|
|
->withClaim('aud', 'your_audience'); // aud: 受众 |
|
|
->withIssuer('your_issuer') // iss: 发行人 |
|
|
|
|
|
->withSubject('your_subject') // sub: 主题 |
|
|
|
|
|
->withAudience('your_audience'); // aud: 受众 |
|
|
|
|
|
|
|
|
// 添加自定义 Claims |
|
|
// 添加自定义 Claims |
|
|
foreach ($claims as $key => $value) { |
|
|
foreach ($claims as $key => $value) { |
|
|
$token = $token->withClaim($key, $value); |
|
|
$token = $token->withClaim($key, $value); // 自定义声明仍然可以使用 withClaim |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 构建并签名 Token |
|
|
// 构建并签名 Token |
|
|
@ -58,4 +65,83 @@ class JWTService |
|
|
|
|
|
|
|
|
return []; |
|
|
return []; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// app/service/JWTService.php |
|
|
|
|
|
namespace app\service; |
|
|
|
|
|
|
|
|
|
|
|
use Lcobucci\JWT\Builder; |
|
|
|
|
|
use Lcobucci\JWT\Signer\Hmac\Sha256; |
|
|
|
|
|
use Lcobucci\JWT\Signer\Key\InMemory; |
|
|
|
|
|
use Lcobucci\JWT\Token; |
|
|
|
|
|
use DateTimeImmutable; |
|
|
|
|
|
|
|
|
|
|
|
class JWTService |
|
|
|
|
|
{ |
|
|
|
|
|
private $secret; |
|
|
|
|
|
|
|
|
|
|
|
public function __construct() |
|
|
|
|
|
{ |
|
|
|
|
|
$this->secret = config('jwt.secret'); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function createToken(array $claims): string |
|
|
|
|
|
{ |
|
|
|
|
|
$signer = new Sha256(); |
|
|
|
|
|
$key = InMemory::plainText($this->secret); |
|
|
|
|
|
|
|
|
|
|
|
$now = new DateTimeImmutable(); // 当前时间 |
|
|
|
|
|
|
|
|
|
|
|
$builder = new Builder(); |
|
|
|
|
|
|
|
|
|
|
|
// 设置发行时间和过期时间 |
|
|
|
|
|
$secondsToAdd = (int) config('jwt.token_ttl'); |
|
|
|
|
|
$expiresAt = $now->add(new \DateInterval('PT' . $secondsToAdd . 'S')); |
|
|
|
|
|
|
|
|
|
|
|
$token = $builder |
|
|
|
|
|
->issuedAt($now) // iat: 发行时间 |
|
|
|
|
|
->expiresAt($expiresAt) // exp: 过期时间 |
|
|
|
|
|
|
|
|
|
|
|
// 使用辅助方法设置注册声明 |
|
|
|
|
|
->withRegisteredClaim('iss', 'your_issuer') // iss: 发行人 |
|
|
|
|
|
->withRegisteredClaim('sub', 'your_subject') // sub: 主题 |
|
|
|
|
|
->withRegisteredClaim('aud', 'your_audience'); // aud: 受众 |
|
|
|
|
|
|
|
|
|
|
|
// 添加自定义 Claims |
|
|
|
|
|
foreach ($claims as $key => $value) { |
|
|
|
|
|
$token = $token->withClaim($key, $value); // 自定义声明仍然可以使用 withClaim |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 构建并签名 Token |
|
|
|
|
|
$signedToken = $token->sign($signer, $key); |
|
|
|
|
|
|
|
|
|
|
|
return (string) $signedToken; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function verifyToken(string $token): array |
|
|
|
|
|
{ |
|
|
|
|
|
try { |
|
|
|
|
|
$parser = new \Lcobucci\JWT\Parser(); |
|
|
|
|
|
$token = $parser->parse($token); |
|
|
|
|
|
|
|
|
|
|
|
if ($token->verify(new Sha256(), InMemory::plainText($this->secret))) { |
|
|
|
|
|
return $token->getClaims(); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (\Exception $e) { |
|
|
|
|
|
// 处理异常 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return []; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 辅助方法用于设置注册声明。 |
|
|
|
|
|
* |
|
|
|
|
|
* @param string $claimName |
|
|
|
|
|
* @param mixed $claimValue |
|
|
|
|
|
* @return \Lcobucci\JWT\Builder |
|
|
|
|
|
*/ |
|
|
|
|
|
private function withRegisteredClaim(string $claimName, $claimValue): Builder |
|
|
|
|
|
{ |
|
|
|
|
|
return (new Builder())->withClaim($claimName, $claimValue); |
|
|
|
|
|
} |
|
|
} |
|
|
} |