70 lines
2.0 KiB
PHP
70 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace app\mzl\modules\jwt\service;
|
|
|
|
use Firebase\JWT\JWT as FirebaseJWT;
|
|
use Firebase\JWT\Key;
|
|
use support\exception\BusinessException;
|
|
|
|
class JwtService
|
|
{
|
|
protected $secretKey;
|
|
protected $algorithm;
|
|
protected $issuer;
|
|
protected $expiration;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->secretKey = getenv('JWT_SECRET_KEY') ?: 'default_secret_key';
|
|
$this->algorithm = getenv('JWT_ALGORITHM') ?: 'HS256';
|
|
$this->issuer = getenv('JWT_ISSUER') ?: 'domain.com';
|
|
$this->expiration = (int)(getenv('JWT_EXPIRATION') ?: 3600);
|
|
}
|
|
|
|
/**
|
|
* 生成 JWT 令牌
|
|
*
|
|
* @param array $payload
|
|
* @return string
|
|
* @throws BusinessException
|
|
*/
|
|
public function generateToken(array $payload): string
|
|
{
|
|
$defaultPayload = [
|
|
'iss' => $this->issuer,
|
|
'iat' => time(),
|
|
'nbf' => time(),
|
|
'exp' => time() + $this->expiration,
|
|
];
|
|
|
|
$payload = array_merge($defaultPayload, $payload);
|
|
|
|
try {
|
|
return FirebaseJWT::encode($payload, $this->secretKey, $this->algorithm);
|
|
} catch (\Exception $e) {
|
|
throw new BusinessException("令牌生成失败:" . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 验证 JWT 令牌
|
|
*
|
|
* @param string $token
|
|
* @return object
|
|
* @throws BusinessException
|
|
*/
|
|
public function verifyToken(string $token)
|
|
{
|
|
try {
|
|
return FirebaseJWT::decode($token, new Key($this->secretKey, $this->algorithm));
|
|
} catch (\Firebase\JWT\ExpiredException $e) {
|
|
throw new BusinessException('令牌已过期', 401);
|
|
} catch (\Firebase\JWT\SignatureInvalidException $e) {
|
|
throw new BusinessException('无效的令牌签名', 401);
|
|
} catch (\Firebase\JWT\BeforeValidException $e) {
|
|
throw new BusinessException('令牌尚未生效', 401);
|
|
} catch (\Exception $e) {
|
|
throw new BusinessException('令牌验证失败:' . $e->getMessage(), 400);
|
|
}
|
|
}
|
|
} |