tp6封装jwt


参考地址

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');

    }


}