php实现jwt签名、验证
composer下有个包,可以用来实现jwt,我们重新包装下拿来用。
1、安装composer包
composer require firebase/php-jwt
2、编写一个JwtService的类
<?php
use Firebase\JWT\JWT;
class JwtService
{
private $key;
public function __construct()
{
$this->key = '123456'; //这个秘钥需要保护好,生产环境建议配置化,不要硬编码到代码里。
}
public function getToken($data)
{
$domain = $_SERVER['SERVER_NAME'];
$key = $this->key; //key
$time = time(); //当前时间
$token = [
'iss' => $domain, //签发者 可选
'aud' => $domain, //接收该JWT的一方,可选
'iat' => $time, //签发时间
'nbf' => $time, //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
'exp' => $time + 3600 * 24 * 10, //过期时间,这里设置10天,这里也可以配置化处理
'data' => $data, //自定义信息,不要定义敏感信息,一般放用户id,足以。
];
return JWT::encode($token, $key); //输出Token
}
/**
* 校验jwt权限API
* @return [type] [description]
*/
public function checkToken()
{
if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
return 'token不存在,请重新登录!';
}
$jwt = $_SERVER['HTTP_AUTHORIZATION'];
$key = $this->key;
try {
JWT::$leeway = 60; //当前时间减去60,把时间留点余地
$decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
$arr = (array) $decoded;
} catch (\Exception $e) {
//Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
return $e->getMessage();
}
return (array) $arr['data'];
}
}
3、测试,一般jwt使用分两步走,
一步是签名下发到客户端,login.php
<?php
require './vendor/autoload.php';
require './JwtService.php';
//用户发送账号密码过来,验证过后,就签发秘钥
$jwt = new JwtService();
$uid = 1;
$data = ['uid' => $uid];
$res = $jwt->getToken($data);
echo json_encode(['token' => $res, 'status' => 0]);
另外一步就是客户端拿到了签名数据,下次请求就带着这个签名数据过来服务器端,服务器端得到后,就开始验签。index.php
<?php
require './vendor/autoload.php';
require './JwtService.php';
$jwt = new JwtService();
$res = $jwt->checkToken();
if (is_array($res)) {
echo "用戶UID" . $res['uid'];
} else {
echo "错误!";
}
jwt相较于session,各自有自己的特点,开发的时候,应该根据实际的场景使用不同的机制来验证客户端的身份。
jwt的缺点,下发的签名一旦给了客户端,除了过期,就无法主动剔除,需要自己在代码逻辑重新处理。
还有就是为了避免签名被盗,强烈建议使用https,都什么时代了,还是用http,网络安全不可忽视啊。
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
继续浏览有关 php 的文章
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。