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