1、composer 安装JWT
github地址:https://github.com/firebase/php-jwt
composer require firebase/php-jwt
2、生成token
$objToken = new \Token();
$token_data = [
'user_id' => $user_info['id'],
];
$token_res = $objToken->createToken($token_data);
if($token_res['status'] == '200'){
$user_info['token'] = $token_res['token'];
$this->dataJsonReturn(1,'登录成功',$user_info);
}
3、验证token
项目原因,笔者使用的的前端通过header传递authorization参数来提交token值。
public function checkUToken(){
$jw_token = new \Token();
$header = \request()->header();
$return_data = [];
if(array_key_exists('authorization',$header)){
$this->utoken = $header['authorization'];
}
if($this->utoken){
$jwt_check_res = $jw_token->checkToken($this->utoken);
if($jwt_check_res['status'] == 200){
$data = $jwt_check_res['data'];
$this->user_id = $data['data']->user_id;
return true;
}
}
return false;
}
4、基于JWT的封装Token类
<?php
/**
* Created by .
*/
class Token
{
private $tokenKey = 'get_the_data';
/**
* @Notes: 创建token
* @Interface createToken
* @param string $data
* @param string $exp_time
* @param string $scopes
* @return array
*/
public function createToken($data="",$exp_time="",$scopes=""){
//JWT标准规定的声明,但不是必须填写的;
//iss: jwt签发者
//sub: jwt所面向的用户
//aud: 接收jwt的一方
//exp: jwt的过期时间,过期时间必须要大于签发时间
//nbf: 定义在什么时间之前,某个时间点后才能访问
//iat: jwt的签发时间
//jti: jwt的唯一身份标识,主要用来作为一次性token。
//公用信息
$return_data = [];
try{
$key = $this->tokenKey;
$time = time();//当前时间
//$token['iss']=''; //签发者 可选
//$token['aud']=''; //接收该JWT的一方,可选
$token['iat'] = $time; //签发时间
$token['nbf'] = $time; //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
if($scopes){
$token['scopes'] = $scopes; //token标识,请求接口的token
}
if(!$exp_time){
$exp_time = 7200;//默认=2小时过期
}
$token['exp'] = $time + $exp_time; //token过期时间,这里设置2个小时
if($data){
$token['data'] = $data; //自定义参数
}
$json = \Firebase\JWT\JWT::encode($token,$key);
$return_data['status']="200";//
$return_data['msg']='success';
$return_data['token']= $json;//返回的数据
return $return_data; //返回信息
}catch (\Firebase\JWT\ExpiredException $exception){
//签名不正确
$return_data['status'] = "104";//101=签名不正确
$return_data['msg'] = $exception->getMessage();
$return_data['data'] = "";//返回的数据
return $return_data; //返回信息
}catch (\think\Exception $exception){
//其他错误
$return_data['status'] = "199";//199=签名不正确
$return_data['msg'] = $exception->getMessage();
$return_data['data'] = "";//返回的数据
return $return_data; //返回信息
}
}
/**
* @Notes: 验证token是否有效,默认验证exp,nbf,iat时间
* @Interface checkToken
* @param $jwt
* @return array
*/
public function checkToken($jwt){
$key = $this->tokenKey;
$return_data = [];
try {
\Firebase\JWT\JWT::$leeway = 60;//当前时间减去60,把时间留点余地
$decoded = \Firebase\JWT\JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
$arr = (array)$decoded;
$return_data['status']="200";//200=成功
$return_data['msg']="success";//
$return_data['data']=$arr;//返回的数据
return $return_data; //返回信息
} catch(\Firebase\JWT\SignatureInvalidException $e) {
//签名不正确
$return_data['status']="101";//101=签名不正确
$return_data['msg']=$e->getMessage();
$return_data['data']="";//返回的数据
}catch(\Firebase\JWT\BeforeValidException $e) {
// 签名在某个时间点之后才能用
$return_data['status']="102";
$return_data['msg']=$e->getMessage();
$return_data['data']="";//返回的数据
}catch(\Firebase\JWT\ExpiredException $e) {
// token过期
$return_data['status']="103";//103=签名不正确
$return_data['msg']=$e->getMessage();
$return_data['data']="";//返回的数据
}catch(\Exception $e) {
//其他错误
$return_data['status']="199";//199=签名不正确
$return_data['msg']=$e->getMessage();
$return_data['data']="";//返回的数据
}
return $return_data;
//Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
}
}