前言
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
1.在框架中 安装 JWT插件
composer require firebase/php-jwt
2.我封装好的 JWT类 直接使用 建议放在 目录extent/tools
namespace tools\\jwt;
use Firebase\\JWT\\BeforeValidException;
use Firebase\\JWT\\ExpiredException;
use Firebase\\JWT\\JWT;
use Firebase\\JWT\\SignatureInvalidException;
use PHPUnit\\Framework\\ExpectationFailedException;
use think\\Exception;
class GetJwt
{
/**
* @param $data传来的数据
* @return string
* 生成token
*/
public function setToken($key,$data)
{
$key = $key; //key
$time = time(); //当前时间
$token = [
'iss' => 'IronMenZFB', //签发者 可选
'aud' => '', //接收该JWT的一方,可选
'iat' => $time, //签发时间
'nbf' => $time , //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
'exp' => $time+7200, //过期时间,这里设置2个小时
'data' =>$data
];
return JWT::encode($token, $key); //输出Token
}
/**
* @param $token
* @return mixed
* 解析token
*/
public function checkToken($key,$token)
{
$key = $key; //key要和签发的时候一样
$jwt = $token; //签发的Token
try {
JWT::$leeway = 60;//当前时间减去60,把时间留点余地
$decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
$arr = (array)$decoded;
return $arr;
} catch(SignatureInvalidException $e) { //签名不正确
echo $e->getMessage();
}catch(BeforeValidException $e) { // 签名在某个时间点之后才能用
echo $e->getMessage();
}catch(ExpiredException $e) { // token过期
echo $e->getMessage();
}catch(Exception $e) { //其他错误
echo $e->getMessage();
}
//Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
}
}
3.JWT的使用方法
登录时,认证用户成功 生成 token 放入用户信息 切记 不要放密码
/**
* 用户登录
* @param Request $request
* @return \\think\\response\\Json
* author: IronMenZFB
* date:ct
*/
public function isLogin(Request $request)
{
if ($request->isPost()){
$data =$request->param('data');
$validate = new \\app\\index\\validate\\User;
if (!$validate->check($data)) return jsonApi(600,$validate->getError());
$is_users = Lsusers::verifyUser($data);//验证 用户
if (!$is_users) return jsonApi(600,'账户密码错误');
//扩展 账户频繁登录
$token = Lsusers::setToken($is_users);//设置JWt
return jsonApi(200,'登录成功',$token);
}else{
return jsonApi(700,'错误无响应');
}
}
4.使用中间件来解析JWTtoken 获取用户的数据
public function handle($request, \\Closure $next)
{
$token=$request->header('token');
if (!$token) return jsonApi(700,'无效用户');
$userInfo = Lsusers::checkToken($token);
if (!$userInfo) return jsonApi($userInfo['code'], $userInfo['msg']);
$request->userInfo = $userInfo;
$request->uid = $userInfo['id'];
unset($token);
return $next($request);
}
5.可以到官方文档去看一下 中间件的使用问题