参考地址
http://www.koukousky.com/back/2483.html
<?php
namespace tools\jwt;
use DateTimeImmutable;
use DateTimeZone;
use InvalidArgumentException;
use Lcobucci\Clock\SystemClock;
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Validation\Constraint\IssuedBy;
use Lcobucci\JWT\Validation\Constraint\PermittedFor;
use Lcobucci\JWT\Validation\Constraint\ValidAt;
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
class Token
{
//配置属性
private static $_config = [
'audience' => 'http://www.pyg.com',//接收人
'id' => '3f2g57a92aa',//jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
'sign' => 'pinyougou',//签名密钥,服务端定义好的不要暴露
'issuer' => 'http://adminapi.pyg.com',//签发人
'expire' => 3600 * 24 //有效期 1天
];
//生成配置对象
private static function getConfig()
{
return Configuration::forSymmetricSigner(new Sha256(), InMemory::plainText(self::$_config['id']));
}
//生成token
public static function getToken($user_id)
{
$config = self::getConfig();
$now = new DateTimeImmutable();
return $config->builder()
->issuedBy(self::$_config['issuer'])
//接收人 // canOnlyBeUsedBy方法在4.x中将会被移除被permittedFor替代
->permittedFor(self::$_config['audience'])
//唯一标志
->identifiedBy(self::$_config['id'])
//签发时间
->issuedAt($now)
//生效时间(立即生效:签发时间前一秒)
->canOnlyBeUsedAfter($now->modify('-1 second'))
//过期时间
->expiresAt($now->modify('+20 second'))
//用户id // with方法在4.x中将会被移除被withClaim替代
->withClaim('user_id', $user_id)
//签名
->getToken($config->signer(), $config->signingKey())->toString();
}
//从token中获取用户id (包含token的校验)
public static function getUserId($token)
{
$config = self::getConfig();
//注销token逻辑
$delete_token = cache('delete_token') ?: [];
if (in_array($token, $delete_token)) {
//token已被删除(注销)
return null;
}
//token解析异常必须要用try catch抓取 当JWT不是字符串或无效时会抛出异常
try {
//解析token,
$token = $config->parser()->parse((string)$token);
} catch (\Exception $e) {
return null;
}
//验证签发人
$issued = new IssuedBy(self::$_config['issuer']);
if (!$config->validator()->validate($token, $issued)) {
return null;
}
//验证接收人
$audience = new PermittedFor(self::$_config['audience']);
if (!$config->validator()->validate($token, $audience)) {
return null;
}
//验证token是否过期
$timezone = new DateTimeZone('Asia/Shanghai');
$now = new SystemClock($timezone);
$valid_at = new ValidAt($now);
if (!$config->validator()->validate($token, $valid_at)) {
return null;
}
//从token中取出user_id
return $token->claims()->get('user_id');
}
}