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.
189 lines
5.1 KiB
189 lines
5.1 KiB
<?php
|
|
/**
|
|
* Created by 花密欧团队.
|
|
* User: 云掌.帮德
|
|
* Date: 2020/3/8 22:30
|
|
* Desc: * Desc: https://github.com/lcobucci/jwt 4.1.2版本
|
|
*/
|
|
|
|
namespace auth;
|
|
|
|
use app\api\model\Token;
|
|
use Lcobucci\JWT\Configuration;
|
|
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
|
use Lcobucci\JWT\Signer\Key\InMemory;
|
|
use Lcobucci\JWT\Validation\Constraint;
|
|
|
|
class JwtAuth
|
|
{
|
|
|
|
private $token = '';
|
|
|
|
private $refresh_token = '';
|
|
|
|
private $userdata = []; //参合用户信息
|
|
|
|
private $host = '';
|
|
|
|
private $jti_nonce = '';
|
|
|
|
private $token_key = ''; //密钥的加解密key
|
|
|
|
private $expire_time = '';
|
|
|
|
private $config = null; //jwt配置对象
|
|
|
|
private static $instance = null;
|
|
|
|
private function __construct()
|
|
{
|
|
//读取配置信息
|
|
$_config = config('jwtauth.web');
|
|
$this->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;
|
|
}
|
|
|
|
}
|