133 lines
4.1 KiB
PHP
133 lines
4.1 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace app\service;
|
||
|
|
||
|
use DateTimeImmutable;
|
||
|
use DateTimeZone;
|
||
|
use Exception;
|
||
|
use Lcobucci\Clock\SystemClock;
|
||
|
use Lcobucci\JWT\Configuration;
|
||
|
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||
|
use Lcobucci\JWT\Signer\Key\InMemory;
|
||
|
use Lcobucci\JWT\UnencryptedToken;
|
||
|
use Lcobucci\JWT\Validation\Constraint\IssuedBy;
|
||
|
use Lcobucci\JWT\Validation\Constraint\LooseValidAt;
|
||
|
use Lcobucci\JWT\Validation\Constraint\PermittedFor;
|
||
|
use Lcobucci\JWT\Validation\Constraint\ValidAt;
|
||
|
|
||
|
class Jwt
|
||
|
{
|
||
|
private static $secret = 'lF9XkOMfpsR0ODVfbasY2HtDrIps8GIX';
|
||
|
private static $expire = 86400 * 3;//秒
|
||
|
private static $iss = 'dxtc';//jwt签发者
|
||
|
private static $sub = 'dxtc-customer';//jwt所面向的用户
|
||
|
private static $aud = 'dxtc-customer';//接受jwt的一方
|
||
|
|
||
|
private static function config(): Configuration
|
||
|
{
|
||
|
return Configuration::forSymmetricSigner(
|
||
|
// You may use any HMAC variations (256, 384, and 512)
|
||
|
new Sha256(),
|
||
|
// replace the value below with a key of your own!
|
||
|
InMemory::base64Encoded(self::$secret)
|
||
|
// You may also override the JOSE encoder/decoder if needed by providing extra arguments here
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取token有效期 单位秒
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public static function expire(): int
|
||
|
{
|
||
|
return self::$expire;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 编码
|
||
|
*
|
||
|
* @param $data
|
||
|
* @param int $expire
|
||
|
* @return string
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public static function generate($data, int $expire = 0): string
|
||
|
{
|
||
|
$expire = $expire <= 0 ? self::$expire : $expire;
|
||
|
$now = new DateTimeImmutable('now', new DateTimeZone('Asia/ShangHai'));
|
||
|
|
||
|
$token = self::config()->builder()
|
||
|
// Configures the issuer (iss claim)
|
||
|
->issuedBy(self::$iss)
|
||
|
// Configures the audience (aud claim)
|
||
|
->permittedFor(self::$aud)
|
||
|
// Configures the id (jti claim)
|
||
|
// ->identifiedBy($this->jti)
|
||
|
// Configures the time that the token was issue (iat claim)
|
||
|
->issuedAt($now)
|
||
|
// Configures the expiration time of the token (exp claim)
|
||
|
->expiresAt($now->modify(sprintf('+%d seconds', $expire)))
|
||
|
// Configures a new claim, called "uid"
|
||
|
->withClaim('data', $data)
|
||
|
// Configures a new header, called "foo"
|
||
|
// ->withHeader('foo', 'bar')
|
||
|
// Builds a new token
|
||
|
->getToken(self::config()->signer(), self::config()->signingKey());
|
||
|
|
||
|
return $token->toString();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 解析
|
||
|
*
|
||
|
* @param string $tokenStr
|
||
|
* @return array|mixed
|
||
|
*/
|
||
|
public static function parse(string $tokenStr)
|
||
|
{
|
||
|
$config = self::config();
|
||
|
|
||
|
try {
|
||
|
$token = $config->parser()->parse($tokenStr);
|
||
|
assert($token instanceof UnencryptedToken);
|
||
|
return $token->claims()->all()['data'] ?? [];
|
||
|
} catch (Exception $e) {
|
||
|
return [];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 验证token
|
||
|
*
|
||
|
* @param string $tokenStr
|
||
|
* @return bool
|
||
|
*/
|
||
|
public static function validate(string $tokenStr): bool
|
||
|
{
|
||
|
$config = self::config();
|
||
|
try {
|
||
|
$token = $config->parser()->parse($tokenStr);
|
||
|
assert($token instanceof UnencryptedToken);
|
||
|
|
||
|
//验证签发人iss是否正确
|
||
|
$validateIssued = new IssuedBy(self::$iss);
|
||
|
$config->setValidationConstraints($validateIssued);
|
||
|
//验证客户端aud是否匹配
|
||
|
$validateAud = new PermittedFor(self::$aud);
|
||
|
$config->setValidationConstraints($validateAud);
|
||
|
|
||
|
//验证是否过期 exp
|
||
|
$timezone = new DateTimeZone('Asia/Shanghai');
|
||
|
$now = new SystemClock($timezone);
|
||
|
$validateExpired = new LooseValidAt($now);
|
||
|
$config->setValidationConstraints($validateExpired);
|
||
|
|
||
|
$constraints = $config->validationConstraints();
|
||
|
|
||
|
return $config->validator()->validate($token, ...$constraints);
|
||
|
} catch (Exception $e) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|