133 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			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 = 'mBC6v1sOKVvbdEitdSBenu59nfNfhwkedkJVNabosTw=';
 | 
						|
    private static $expire = 7200 * 10;//秒
 | 
						|
    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;
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |