tp5.1 创建签名 验证签名 firebase php-jwt token

时间:2024-04-09 19:32:59

1、安装vendor扩展包firebase php-jwt token

教程:https://blog.csdn.net/haibo0668/article/details/83861702

2、设置版本

教程:https://blog.csdn.net/haibo0668/article/details/83863789

3、控制器代码   测试网址:http://www.xxx.com/api/v1/index

<?php
namespace app\api\controller\v1;
use \Firebase\JWT\JWT; //导入JWT

class Index extends Common{
	
	    /**
	     * 头部 公共参数
	     * @param array $header 头部参数数组
	     * @param string $alg 声明签名算法为SHA256
	     * @return string $typ 声明类型为jwt
	    */
		private static $header=array(
		    'alg'=>'HS256', //生成signature的算法 //声明签名算法为SHA256
		    'typ'=>'JWT'  //声明类型为jwt
		);
 
	    /**
	     * 创建 token
		   * @param array $data 必填 自定义参数数组
		   * @param integer $exp_time 必填 token过期时间 单位:秒 例子:7200=2小时
		   * @param string $scopes 选填 token标识,请求接口的token
		   * @return string
	    */
	    public function createToken($data="",$exp_time=0,$scopes=""){
		
				//JWT标准规定的声明,但不是必须填写的;
						//iss: jwt签发者
						//sub: jwt所面向的用户
						//aud: 接收jwt的一方
						//exp: jwt的过期时间,过期时间必须要大于签发时间
						//nbf: 定义在什么时间之前,某个时间点后才能访问
						//iat: jwt的签发时间
						//jti: jwt的唯一身份标识,主要用来作为一次性token。
				//公用信息
			try {
	                $key=TokenKey;
					$time = time(); //当前时间
					$token['iss']='http://www.fn321.com|Fneducms'; //签发者 可选
					$token['aud']='http://www.fn321.com|Fneducms'; //接收该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; //自定义参数
					}
					$token = [
					        	'iss' => 'http://www.fn321.com|Fneducms', //签发者 可选
					           	'aud' => 'http://www.fn321.com|Fneducms', //接收该JWT的一方,可选
					            'iat' => $time, //签发时间
					            'nbf' => $time, //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
					            'scopes' => $scopes, //token标识,请求接口的token
					            'exp' => $time+$exp_time, //token过期时间,这里设置2个小时
					            'params' => $data
			        ];
	
					$json = JWT::encode($token,$key);
				    //Header("HTTP/1.1 201 Created");
					//return json_encode($json); //返回给客户端token信息
					return $json; //返回给客户端token信息
				
			}catch(\Firebase\JWT\ExpiredException $e){  //签名不正确
		       		$returndata['code']="104";//101=签名不正确
		       		$returndata['msg']=$e->getMessage();
		       		$returndata['data']="";//返回的数据
		       		return json_encode($returndata); //返回信息
			}catch(Exception $e) {  //其他错误
		       		$returndata['code']="199";//199=签名不正确
		       		$returndata['msg']=$e->getMessage();
		       		$returndata['data']="";//返回的数据
		       		return json_encode($returndata); //返回信息
			}
	    }
	    
	    
	    /**
	     * 验证token是否有效,默认验证exp,nbf,iat时间
		 * @param string $jwt 需要验证的token
	     * @return string $msg 返回消息
	    */
		public function checkToken($jwt){
			$key=TokenKey;
	
			//$jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC93d3cuZm4zMjEuY29tfEZuZWR1Y21zIiwiYXVkIjoiaHR0cDpcL1wvd3d3LmZuMzIxLmNvbXxGbmVkdWNtcyIsImlhdCI6MTU0MTc1NDQ4MiwibmJmIjoxNTQxNzU0NDgyLCJzY29wZXMiOiJyb2xlX2FjY2VzcyIsImV4cCI6MTU0MTc2MTY4MiwiZGF0YSI6eyJ1c2VyaWQiOjIxLCJ1c2VybmFtZSI6Ilx1Njc0ZVx1NWMwZlx1OWY5OSJ9fQ.eSWijLKzIBpS--wPhtL7zUn-ConFA69-FdpfqfDVtpM"; 
			try {
		       		JWT::$leeway = 60;//当前时间减去60,把时间留点余地
		       		$decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
		       		$arr = (array)$decoded;
		       		
		       		$returndata['code']="200";//200=成功
		       		$returndata['msg']="成功";//
		       		$returndata['data']=$arr;//返回的数据
		       		return json_encode($returndata); //返回信息

		    	} catch(\Firebase\JWT\SignatureInvalidException $e) {  //签名不正确
		    		//echo "2,";
		    		//echo $e->getMessage();
		       		$returndata['code']="101";//101=签名不正确
		       		$returndata['msg']=$e->getMessage();
		       		$returndata['data']="";//返回的数据
		       		return json_encode($returndata); //返回信息
		    	}catch(\Firebase\JWT\BeforeValidException $e) {  // 签名在某个时间点之后才能用
		    		//echo "3,";
		    		//echo $e->getMessage();
		       		$returndata['code']="102";//102=签名不正确
		       		$returndata['msg']=$e->getMessage();
		       		$returndata['data']="";//返回的数据
		       		return json_encode($returndata); //返回信息
		    	}catch(\Firebase\JWT\ExpiredException $e) {  // token过期
		    		//echo "4,";
		    		//echo $e->getMessage();
		       		$returndata['code']="103";//103=签名不正确
		       		$returndata['msg']=$e->getMessage();
		       		$returndata['data']="";//返回的数据
		       		return json_encode($returndata); //返回信息
			   	}catch(Exception $e) {  //其他错误
			   		//echo "5,";
			    	//echo $e->getMessage();
		       		$returndata['code']="199";//199=签名不正确
		       		$returndata['msg']=$e->getMessage();
		       		$returndata['data']="";//返回的数据
		       		return json_encode($returndata); //返回信息
			    }
		    //Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
		}
	    
	    /**
	     * 接口首页 没有内容
	     * @url /api/v1/index
	     * @method POST
	    */
		public function index(){
			//url:http://www.cms.com/api/v1/index
			
					//自定义信息,不要定义敏感信息
					$data['userid']=21;//用户ID
					$data['username']="李10小龙";//用户ID
					$exp_time=7200; //token过期时间,这里设置2个小时
					$scopes='role_access'; //token标识,请求接口的token
					
					//生成签名
					$json = action('createToken',['data'=>$data,'exp_time'=>$exp_time,'scopes'=>$scopes]);
					//echo $json."<br>"; //返回给客户端token信息
					//验证签名
					$checkToken = action('checkToken',['jwt'=>$json]);
					Header("HTTP/1.1 201 Created");
		            echo $checkToken; //返回给客户端token信息

					
		}
		
	    /**
	     * 获取用户登录信息
	     * @url /api/v1.index/login
	     * @method POST
	     * @param integer $page 页数
	     * @param integer $limit 每页个数
	     * @return integer $code 状态码
	     * @return string $msg 返回消息
	    */
		public function login(){
			
				//登录思路:客户端通过用户名密码登录以后,服务端返回给客户端两个token:access_token和refresh_token。
					//access_token:请求接口的token
					//refresh_token:刷新access_token
					//举个例子:比如access_token设置2个小时过期,refresh_token设置7天过期,2小时候后,access_token过期,但是refresh_token还在7天以内,那么客户端通过refresh_token来服务端刷新,服务端重新生成一个access_token;
					//如果refresh_token也超过了7天,那么客户端需要重新登录获取access_token和refresh_token。
					//为了区分两个token,我们在载荷(payload)加一个字段 scopes :作用域。
					//access_token中设置:scopes:role_access
					//refresh_token中设置:scopes:role_refresh
		
					//自定义信息,不要定义敏感信息
						$data['userid']=21;//用户ID
						$data['username']="李小龙";//用户ID
					
					//请求接口的token
						$exp_time1=7200; //token过期时间,这里设置2个小时
						$scopes1='role_access'; //token标识,请求接口的token
						$access_token = action('createToken',['data'=>$data,'exp_time'=>$exp_time1,'scopes'=>$scopes1]);
					
					//刷新refresh_token
						$exp_time2=86400 * 30; //refresh_token过期时间,这里设置30天
						$scopes2='role_refresh'; //token标识,刷新access_token
						$refresh_token = action('createToken',['data'=>$data,'exp_time'=>$exp_time2,'scopes'=>$scopes2]);
			
//					//公用信息
//					$token = [
//					        	'iss' => 'http://www.helloweba.net', //签发者 可选
//					           	'aud' => 'http://www.helloweba.net', //接收该JWT的一方,可选
//					            'iat' => $time, //签发时间
//					            'nbf' => $time, //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
//					            'data' => $data
//			        ];
//			    //请求接口的token 用户名登录验证通过时生成的
//							$access_token = $token; // access_token
//							$access_token['scopes'] = 'role_access'; //token标识,请求接口的token
//							$access_token['exp'] = $time+7200; //access_token过期时间,这里设置2个小时
//			    //刷新access_token
//							$refresh_token = $token; //refresh_token
//							$refresh_token['scopes'] = 'role_refresh'; //token标识,刷新access_token
//							$refresh_token['exp'] = $time+(86400 * 30); //refresh_token过期时间,这里设置30天
			
					$jsonList = [
							'access_token'=>$access_token,
							'refresh_token'=>$refresh_token,
							'token_type'=>'bearer' //token_type:表示令牌类型,该值大小写不敏感,这里用bearer
					];
			    Header("HTTP/1.1 201 Created");
				echo json_encode($jsonList); //返回给客户端token信息
		}
 

}

4、用户登录接口  http://www.xxx.com/api/v1.index/login

 

 

 

注意:

$key常量放到公共文件中:路径:\application\common.php

define('Key', 'ffeyJ0eXAiOiJKV1QiLCJhbGciOi5');//API接口$key值

tp5.1 创建签名 验证签名 firebase php-jwt token