host = $_config['host']; $this->jti_nonce = $_config['jti_nonce']; $this->expire_time = $_config['expire_time']; $this->token_key = $_config['token_key']; //定义加密配置 $this->config = Configuration::forSymmetricSigner( new Sha256(), InMemory::plainText($this->token_key) ); } /** * 禁止克隆 */ private function __clone() { // TODO: Implement __clone() method. } /** * 返回单例对象 * @return JwtAuth|null */ public static function getInstance() { if (!self::$instance instanceof self) { self::$instance = new self(); } return self::$instance; } /** * 设置jwt密钥并返回当前实例对象 * @return $this */ public function setToken($userdata = []) { //读取用户信息 $this->userdata = $userdata; $this->createToken(); return $this; } /** * 获取当前生成的jwt密钥 * @return string */ public function getToken() { return $this->token; } public function checkToken($token) { return $this->checkJwtToken($token); } /** * 创建刷新token */ public function createRefreshToken(Token $token) { $refresh_token = password_hash(mt_rand(99999, 999999) . microtime(), PASSWORD_DEFAULT); $data = [ 'refresh_token' => $refresh_token, 'token' => $this->token, 'user_id' => $this->userdata['id'], 'site_id' => $this->userdata['site_id'] ]; $token->add($data); return $refresh_token; } /** * 创建jwttoken */ private function createToken() { $now = new \DateTimeImmutable(); $token = $this->config->builder() // jwt签发者 ->issuedBy('ahbmz.com') // 配置访问对象Configures the audience (aud claim) ->permittedFor($this->host) // jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 ->identifiedBy($this->jti_nonce) // jwt的签发时间 ->issuedAt($now) // Configures the time that the token can be used (nbf claim) ->canOnlyBeUsedAfter($now) // Configures the expiration time of the token (exp claim) ->expiresAt($now->modify($this->expire_time)) // Configures a new claim, called "uid" ->withClaim('user_id', $this->userdata['id']) ->withClaim('site_id', $this->userdata['site_id']) // Configures a new header, called "foo" // ->withHeader('foo', 'bar') // Builds a new token ->getToken($this->config->signer(), $this->config->signingKey()); // halt($token->claims()->get('uid')); $this->token = $token->toString(); } private function checkJwtToken($header_token) { if (empty($header_token)) { return false; } $token = $this->config->parser()->parse($header_token); $constraint = new Constraint\SignedWith($this->config->signer(), $this->config->verificationKey()); $this->config->setValidationConstraints($constraint); $constraints = $this->config->validationConstraints(); //验证 if ($this->config->validator()->validate($token, ...$constraints)) { $now = new \DateTimeImmutable(); // $clock = new FrozenClock($now); // $a = new Constraint\LooseValidAt($clock,new \DateInterval('P2W')); //判断是否过期 if ($token->isExpired($now)) { return false; } //判断当前jwt是否生效 if (!$token->isMinimumTimeBefore($now)) { return false; } //判断域名是否正确 if (!$token->isPermittedFor($this->host)) { return false; } //判断签发者是否正确 if (!$token->hasBeenIssuedBy('ahbmz.com')) { return false; } return [ 'user_id' => $token->claims()->get('user_id'), 'site_id' => $token->claims()->get('site_id'), ]; } return false; } }