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 = '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;
 | |
|         }
 | |
|     }
 | |
| } |