zzwy2/app/service/Jwt.php

133 lines
4.1 KiB
PHP
Executable File

<?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;
}
}
}