捕梦者基础框架API接口
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

<?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;
}
}