You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.5 KiB
128 lines
4.5 KiB
<?php
|
|
|
|
namespace app\api\service;
|
|
|
|
use Lcobucci\JWT\Configuration;
|
|
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
|
use Lcobucci\JWT\Signer\Key\InMemory;
|
|
use DateTimeImmutable;
|
|
use Lcobucci\JWT\Token\Plain;
|
|
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
|
|
use Lcobucci\JWT\Validation\Constraint\SignedWith;
|
|
|
|
class LcJWTService
|
|
{
|
|
protected static $url = 'https://douyin.xingtongworld.com/';
|
|
/**
|
|
* 配置秘钥加密
|
|
* @return Configuration
|
|
*/
|
|
public static function getConfig()
|
|
{
|
|
$configuration = 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(config('jwt.secret'))
|
|
// You may also override the JOSE encoder/decoder if needed by providing extra arguments here
|
|
);
|
|
return $configuration;
|
|
}
|
|
|
|
/**
|
|
* 签发令牌
|
|
*/
|
|
public static function createToken(int $userId,string $uname)
|
|
{
|
|
$config = self::getConfig();
|
|
assert($config instanceof Configuration);
|
|
|
|
$now = new DateTimeImmutable();
|
|
|
|
$token = $config->builder()
|
|
// 签发人
|
|
->issuedBy(self::$url)
|
|
// 受众
|
|
->permittedFor(self::$url)
|
|
// JWT ID 编号 唯一标识
|
|
->identifiedBy($userId)
|
|
// 签发时间
|
|
->issuedAt($now)
|
|
// 在1分钟后才可使用
|
|
// ->canOnlyBeUsedAfter($now->modify('+1 minute'))
|
|
// 过期时间1小时
|
|
->expiresAt($now->modify('+1 hour'))
|
|
// 自定义uid 额外参数
|
|
->withClaim('uid', $userId)
|
|
->withClaim('name', $uname)
|
|
// 自定义header 参数
|
|
->withHeader('foo', 'bar')
|
|
// 生成token
|
|
->getToken($config->signer(), $config->signingKey());
|
|
|
|
return $token->toString();
|
|
}
|
|
|
|
/**
|
|
* 解析令牌
|
|
*/
|
|
public static function parseToken(string $token)
|
|
{
|
|
$config = self::getConfig();
|
|
assert($config instanceof Configuration);
|
|
|
|
$token = $config->parser()->parse($token);
|
|
|
|
assert($token instanceof Plain);
|
|
|
|
return [
|
|
'header' => $token->headers(),// Retrieves the token headers
|
|
'claims' => $token->claims()// Retrieves the token claims
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 验证令牌
|
|
*/
|
|
public static function validationToken(string $token, int $userId)
|
|
{
|
|
$config = self::getConfig();
|
|
assert($config instanceof Configuration);
|
|
|
|
$token = $config->parser()->parse($token);
|
|
assert($token instanceof Plain);
|
|
|
|
//Lcobucci\JWT\Validation\Constraint\IdentifiedBy: 验证jwt id是否匹配
|
|
//Lcobucci\JWT\Validation\Constraint\IssuedBy: 验证签发人参数是否匹配
|
|
//Lcobucci\JWT\Validation\Constraint\PermittedFor: 验证受众人参数是否匹配
|
|
//Lcobucci\JWT\Validation\Constraint\RelatedTo: 验证自定义cliam参数是否匹配
|
|
//Lcobucci\JWT\Validation\Constraint\SignedWith: 验证令牌是否已使用预期的签名者和密钥签名
|
|
//Lcobucci\JWT\Validation\Constraint\ValidAt: 验证要求iat,nbf和exp(支持余地配置)
|
|
|
|
//验证jwt id是否匹配
|
|
$validate_jwt_id = new \Lcobucci\JWT\Validation\Constraint\IdentifiedBy($userId);
|
|
$config->setValidationConstraints($validate_jwt_id);
|
|
//验证签发人url是否正确
|
|
$validate_issued = new \Lcobucci\JWT\Validation\Constraint\IssuedBy(self::$url);
|
|
$config->setValidationConstraints($validate_issued);
|
|
//验证客户端url是否匹配
|
|
$validate_aud = new \Lcobucci\JWT\Validation\Constraint\PermittedFor(self::$url);
|
|
$config->setValidationConstraints($validate_aud);
|
|
|
|
//验证是否过期
|
|
$timezone = new \DateTimeZone('Asia/Shanghai');
|
|
$now = new \Lcobucci\Clock\SystemClock($timezone);
|
|
$validate_jwt_at = new \Lcobucci\JWT\Validation\Constraint\ValidAt($now);
|
|
$config->setValidationConstraints($validate_jwt_at);
|
|
|
|
$constraints = $config->validationConstraints();
|
|
|
|
try {
|
|
$config->validator()->assert($token, ...$constraints);
|
|
return true;
|
|
} catch (RequiredConstraintsViolated $e) {
|
|
// list of constraints violation exceptions:
|
|
return $e->getMessage();
|
|
}
|
|
}
|
|
}
|