JWT 使用

JWT 使用

1.jwt 是什么?

JWT是目前流行的跨域认证解决方案,其原理是将用户信息通过加密生成Token,每次请求服务端只需要使用保存的密钥验证Token的正确性,进而不用再保存任何Session数据,使服务端变得无状态。

 

2.JWT 结构

  一个token分为3部分:

    头部(header)

    载荷(payload)

    签名(signature)

3.JWT官方推荐字段:

  iss: jwt签发者

  sub: jwt所面向的用户

  aud: 接收jwt的一方

  exp: jwt的过期时间,这个过期时间必须要大于签发时间

  nbf: 定义在什么时间之前,该jwt都是不可用的.

  iat: jwt的签发时间

  jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

4.使用

4-1.Lcobucci/jwt 3.3版

<?php
namespace app\common\Auth;

use think\facade\Config;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\ValidationData;
use Lcobucci\JWT\Signer\Hmac\Sha256;

class JwtAuth
{
    private $uid = null;

    private $token = null;

    private $decodeToken = null;

    private static $instance = null;

    /**
     * 获取jwtAuth的句柄
     */
    public static function getInstance()
    {
        if(is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 私有化构造函数
     */
    private function __construct()
    {

    }

    /**
     * 私有化clone函数
     */
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * 获取token
     * @return string
     */
    public function getToken()
    {
        return (string)$this->token;
    }

    /**
     * 设置token
     * @param $token
     * @return JwtAuth
     */
    public function setToken($token)
    {
        $this->token = $token;
        return $this;
    }

    /**
     * 设置UID
     * @param $uid
     * @return JwtAuth
     */
    public function setUid($uid)
    {
        $this->uid = $uid;
        return $this;
    }

    /**
     * 获取UID
     */
    public function getUid()
    {
        return $this->uid;
    }

    /**
     * jwt token 编码
     */
    public function encode()
    {
        $signer = new Sha256();
        $time = time();
        $this->token = (new Builder())
            ->issuedBy(Config::get('jwt.issue'))
            ->permittedFor(Config::get('jwt.permitted'))
            ->identifiedBy(Config::get('jwt.identified'))
            ->issuedAt($time)
            ->canOnlyBeUsedAfter($time + 60)// 多少秒之后才能使用这个token(可省略)
            ->expiresAt($time + Config::get('jwt.effective_time'))// 过期时间
            ->withClaim('uid', $this->uid)
            ->getToken($signer, new key(Config::get('jwt.key')));
        return $this;
    }

    /**
     * jwt token 解码
     */
    public function decode()
    {
        if (!$this->decodeToken) {
            $this->decodeToken = (new Parser())->parse((string)$this->token);
            $this->uid = $this->decodeToken->getClaim('uid');
        }
        return $this->decodeToken;
    }



    /**
     * 验证token是否被篡改
     */
    public function verify()
    {
        $signer = new Sha256();
        return $this->decode()->verify($signer, Config::get('jwt.key'));
    }

    /**
     * 校验数据
     */
    public function validate()
    {
        $time = time();
        $data = new ValidationData();
        $data->setAudience(Config::get('jwt.permitted'));
        $data->setIssuer(Config::get('jwt.issue'));
        $data->setCurrentTime($time + 61);  // 因为之前设置了60秒前不能使用
        return $this->decode()->validate($data);
    }
}

  

posted @ 2021-03-16 15:06  今晚丶打老虎  阅读(173)  评论(0)    收藏  举报