了解JWT可以参考:了解JWT
一:下载JWT拓展
在JWT官网中我们可以看到很多php版本的JWT,选择一个JWT进行下载
这里我选择的是lcobucci/jwt,使用composer进行下载
lcobucci/jwt的composer地址:https://packagist.org/packages/lcobucci/jwt
composer require lcobucci/jwt "^3.3.0" #这里我下载的是3.3.0版本
二:lcobucci/jwt使用
lcobucci/jwt使用方法可以参考下载下来的README.md文件(vendor/lcobucci/jwt/README.md)
1:生成JWT
$request = Yii::$app->getRequest();
$signer = new Sha256();//使用Sha256加密,常用加密方式有Sha256,Sha384,Sha512
$time = time();
$tokenBuilder = (new Builder())
->issuedBy($request->getHostInfo()) // 设置发行人
->permittedFor(isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '') // 设置接收
->identifiedBy(Yii::$app->security->generateRandomString(10), true) // 设置id
->issuedAt($time) // 设置生成token的时间
->canOnlyBeUsedAfter($time) // 设置token使用时间(实时使用)
->expiresAt($time + 3600); //设置token过期时间
//定义自己所需字段
$user = ['user_name' => '测试', 'user_no' => '001'];
$tokenBuilder->withClaim('user', $user);
$tokenBuilder->withClaim('ceshi', '测试字段');
//使用Sha256加密生成token对象,该对象的字符串形式为一个JWT字符串
$token = $tokenBuilder->getToken($signer, new Key('jwt_secret'));
echo (string) $token;
2:对JWT进行校验
在正常的开发环境下,我们将生成的JWT字符串传到前端,当前端调用其他接口时,将我们所给的JWT传递到后台,我们后台需要对前端传来的JWT字符串进行校验
下面的$token为我们获取到的前端传递的JWT
$token = (new Parser())->parse($token);
//数据校验
$data = new ValidationData(); // 使用当前时间来校验数据
if (!$token->validate($data)) {
//数据校验失败
return '数据校验失败';
}
//token校验
$signer = new Sha256();//生成JWT时使用的加密方式
if (!$token->verify($signer, new Key('jwt_secret'))) {
//token校验失败
return 'token校验失败';
}
echo '校验成功';
3:获取JWT的相关信息
$token = (new Parser())->parse($token);
$token->getHeaders(); // 获取JWT的Header(头部)信息
$token->getClaims(); // 获取JWT的PayLoad(负载)信息
//获取指定参数的PayLoad(负载)信息
$token->getClaim('jti');
$token->getClaim('user');
三:编写一个JWT类,方便对于JWT的使用
1:创建一个JWT类,代码如下:
'Lcobucci\JWT\Signer\Hmac\Sha256',
'HS384' => 'Lcobucci\JWT\Signer\Hmac\Sha384',
'HS512' => 'Lcobucci\JWT\Signer\Hmac\Sha512',
];
/**
* 实例化JWT生成器
* @see [[Lcobucci\JWT\Builder::__construct()]]
* @return Builder
*/
public function getBuilder(Encoder $encoder = null, ClaimFactory $claimFactory = null)
{
return new Builder($encoder, $claimFactory);
}
/**
* 实例化JWT分析器
* @see [[Lcobucci\JWT\Parser::__construct()]]
* @return Parser
*/
public function getParser(Decoder $decoder = null, ClaimFactory $claimFactory = null)
{
return new Parser($decoder, $claimFactory);
}
/**
* 验证JWT并返回一个令牌类
* function: ValiJwt
* @return Token|null
*/
public function ValiJwt($token, $validate = true, $verify = true)
{
try {
$token = $this->getParser()->parse((string)$token);
} catch (\RuntimeException $e) {
// Yii::warning("Invalid JWT provided: " . $e->getMessage(), 'jwt');
return null;
} catch (\InvalidArgumentException $e) {
// Yii::warning("Invalid JWT provided: " . $e->getMessage(), 'jwt');
return null;
}
if ($validate && !$this->validateToken($token)) {
return null;
}
if ($verify && !$this->verifyToken($token)) {
return null;
}
return $token;
}
/**
* 数据验证
* Validate token
* @param Token $token token object
* @return bool
*/
public function validateToken(Token $token, $currentTime = null)
{
$data = new ValidationData($currentTime);
// @todo Add claims for validation
return $token->validate($data);
}
/**
* Validate token
* @param Token $token token object
* @return bool
*/
public function verifyToken(Token $token)
{
$alg = $token->getHeader('alg');
if (empty($this->supportedAlgs[$alg])) {
throw new InvalidParamException('Algorithm not supported');
}
$signer = Yii::createObject($this->supportedAlgs[$alg]);
return $token->verify($signer, new Key('jwt_secret'));
}
}
2:在配置文件中添加(引入JWT类):
'components' => [
...
'jwt' => [
'class' => 'app\components\Jwt'
],
...
]
3:使用:
Yii::$app->jwt
Yii::$app->jwt->getBuilder() #等同于new Builder()
Yii::$app->jwt->ValiJwt($token);JWT验证