php实现JWT验证的实例教程


Posted in PHP onNovember 26, 2020

JWT,全称 Json web token,是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

php实现JWT,本例使用thinkphp框架,代码如下:

在vendor包中建立Jwt.php,建立类文件

class Jwt {
 
 //头部
 private static $header=array(
  'alg'=>'HS256', //生成signature的算法
  'typ'=>'JWT' //类型
 );
 
 //使用HMAC生成信息摘要时所使用的密钥
 private static $key='123456';
 
 
 /**
  * 获取jwt token
  * @param array $payload jwt载荷 格式如下非必须
  * [
  * 'iss'=>'jwt_admin', //该JWT的签发者
  * 'iat'=>time(), //签发时间
  * 'exp'=>time()+7200, //过期时间
  * 'nbf'=>time()+60, //该时间之前不接收处理该Token
  * 'sub'=>'www.admin.com', //面向的用户
  * 'jti'=>md5(uniqid('JWT').time()) //该Token唯一标识
  * ]
  * @return bool|string
  */
 public static function getToken($payload)
 {
  if(is_array($payload))
  {
   $base64header=self::base64UrlEncode(json_encode(self::$header,JSON_UNESCAPED_UNICODE));
   $base64payload=self::base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE));
   $token=$base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload,self::$key,self::$header['alg']);
   return $token;
  }else{
   return false;
  }
 }
 
 
 /**
  * 验证token是否有效,默认验证exp,nbf,iat时间
  * @param string $Token 需要验证的token
  * @return bool|string
  */
 public static function verifyToken($Token)
 {
  $tokens = explode('.', $Token);
  if (count($tokens) != 3)
   return false;
 
  list($base64header, $base64payload, $sign) = $tokens;
 
  //获取jwt算法
  $base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);
  if (empty($base64decodeheader['alg']))
   return false;
 
  //签名验证
  if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)
   return false;
 
  $payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);
 
  //签发时间大于当前服务器时间验证失败
  if (isset($payload['iat']) && $payload['iat'] > time())
   return false;
 
  //过期时间小宇当前服务器时间验证失败
  if (isset($payload['exp']) && $payload['exp'] < time())
   return false;
 
  //该nbf时间之前不接收处理该Token
  if (isset($payload['nbf']) && $payload['nbf'] > time())
   return false;
 
  return $payload;
 }
 
 
 
 
 /**
  * base64UrlEncode https://jwt.io/ 中base64UrlEncode编码实现
  * @param string $input 需要编码的字符串
  * @return string
  */
 private static function base64UrlEncode($input)
 {
  return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
 }
 
 /**
  * base64UrlEncode https://jwt.io/ 中base64UrlEncode解码实现
  * @param string $input 需要解码的字符串
  * @return bool|string
  */
 private static function base64UrlDecode($input)
 {
  $remainder = strlen($input) % 4;
  if ($remainder) {
   $addlen = 4 - $remainder;
   $input .= str_repeat('=', $addlen);
  }
  return base64_decode(strtr($input, '-_', '+/'));
 }
 
 /**
  * HMACSHA256签名 https://jwt.io/ 中HMACSHA256签名实现
  * @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload)
  * @param string $key
  * @param string $alg 算法方式
  * @return mixed
  */
 private static function signature($input, $key, $alg = 'HS256')
 {
  $alg_config=array(
   'HS256'=>'sha256'
  );
  return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key,true));
 }
}

调用JWT验证的方法,代码如下:

1.构建token方法

public function makeToken(){
	 $uname=$this->uname;	$currtime=time();
	 if(empty($this->uname)){ echo json_encode(array('code'=>-1,'msg'=>'[主账号]参数为空'),JSON_UNESCAPED_UNICODE);	exit(); }	
	 ....
	 //jwt验证
	 vendor("Jwt.Jwt");
	 $jwt = new \Jwt();
//这里构造jwt参数,可以参照jwt规范,各字段可以自行定义内容	 $payload=array('iss'=>'xesport','sub'=>'xxx_player','name'=>$playerName,'iat'=>$currtime,'jti'=>md5(uniqid('JWT').$currtime));
	 $token=$jwt->getToken($payload); $this->token=$token;
	 $url='http://xxx?token='.$token;
	 $data=array('url'=>$url);
	 
	 echo json_encode(array('code'=>1,'data'=>$data,),JSON_UNESCAPED_UNICODE); exit();
 
	}

2.验证token的方法

//验证token
public function verifyToken(){
	 $token=$_REQUEST['token'];
	 if(empty($token)){ echo json_encode(array('code'=>-1,'msg'=>'[token]参数为空!'),JSON_UNESCAPED_UNICODE);	exit(); }
  vendor("Jwt.Jwt");
	 $jwt = new \Jwt();	 
	 $res_token=$jwt->verifyToken($token);
  //var_dump('res_token==',$res_token);
	 if(empty($res_token)){ echo json_encode(array('code'=>-2,'msg'=>'[token]验证失败!'),JSON_UNESCAPED_UNICODE);	exit(); }
	 $playerName=$res_token['name'];
	 //echo $playerName; die;
	 这里可以写从数据库查询验证user是否存在,返回 $userInfo 
	 if(empty($userInfo)){ echo json_encode(array('code'=>-3,'msg'=>'[token]验证用户无效!'),JSON_UNESCAPED_UNICODE);	exit(); }
	 $data=array('username'=>$playerName);
	 echo json_encode(array('code'=>1,'data'=>$data,'msg'=>'[token]验证成功'),JSON_UNESCAPED_UNICODE);	exit();
	}

这样,我们通过控制器方法调用该方法,传递参数token,就可以解析token中包含的认证凭据信息,从而做后续业务处理逻辑。

到此这篇关于php实现JWT验证的文章就介绍到这了,更多相关php实现JWT验证内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
如何使用动态共享对象的模式来安装PHP
Oct 09 PHP
把PHP安装为Apache DSO
Oct 09 PHP
PHP array_multisort()函数的使用札记
Jul 03 PHP
php获取文件夹路径内的图片以及分页显示示例
Mar 11 PHP
浅析ThinkPHP的模板输出功能
Jul 01 PHP
PHP SPL标准库之接口(Interface)详解
May 11 PHP
PHP解密Unicode及Escape加密字符串
May 17 PHP
PHP中遇到的时区问题解决方法
Jul 23 PHP
PHP的压缩函数实现:gzencode、gzdeflate和gzcompress的区别
Jan 27 PHP
Joomla开启SEF的方法
May 04 PHP
php实现评论回复删除功能
May 23 PHP
php面向对象的用户登录身份验证
Jun 08 PHP
PHP替换Word中变量并导出PDF图片的实现方法
Nov 26 #PHP
PHP扩展安装方法步骤解析
Nov 24 #PHP
Cookie跨域问题解决方案代码示例
Nov 24 #PHP
PHP执行linux命令6个函数代码实例
Nov 24 #PHP
PHP获取真实IP及IP模拟方法解析
Nov 24 #PHP
Thinkphp极验滑动验证码实现步骤解析
Nov 24 #PHP
ThinkPhP+Apache+PHPstorm整合框架流程图解
Nov 23 #PHP
You might like
短波收音机简介
2021/03/01 无线电
php获取通过http协议post提交过来xml数据及解析xml
2012/12/16 PHP
php实现zip压缩文件解压缩代码分享(简单易懂)
2014/05/10 PHP
Yii2框架实现注册和登录教程
2016/09/30 PHP
php实现数组纵向转横向并过滤重复值的方法分析
2017/05/29 PHP
基于jquery的滚动鼠标放大缩小图片效果
2011/10/27 Javascript
JS文本框默认值处理详解
2013/07/10 Javascript
jquery foreach使用示例
2013/09/12 Javascript
JS的事件绑定深入认识
2014/06/26 Javascript
Nodejs极简入门教程(一):模块机制
2014/10/25 NodeJs
sails框架的学习指南
2014/12/22 Javascript
jQuery实现防止提交按钮被双击的方法
2015/03/24 Javascript
jQuery使用hide方法隐藏页面上指定元素的方法
2015/03/30 Javascript
JS模拟并美化的表单控件完整实例
2015/08/19 Javascript
Jquery ajax基础教程
2015/11/20 Javascript
AngularJS定时器的使用与移除操作方法【interval与timeout】
2016/12/14 Javascript
Javascript封装id、class与元素选择器方法示例
2017/03/13 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
JS前端知识点总结之内置对象,日期对象和定时器相关操作
2019/07/05 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
Vue自定义组件的四种方式示例详解
2020/02/28 Javascript
vue-cli4.0多环境配置变量与模式详解
2020/12/30 Vue.js
Python基于time模块求程序运行时间的方法
2017/09/18 Python
使用实现XlsxWriter创建Excel文件并编辑
2018/05/04 Python
python 使用递归回溯完美解决八皇后的问题
2020/02/26 Python
Python爬虫之Selenium警告框(弹窗)处理
2020/12/04 Python
Shein英国:女性时尚网上商店
2019/04/10 全球购物
商务日语专业毕业生求职信
2013/10/26 职场文书
求职简历中个人的自我评价
2013/12/25 职场文书
大学生党员自我批评
2014/02/14 职场文书
2014年母亲节演讲稿范文
2014/05/07 职场文书
餐饮服务食品安全责任书
2014/07/25 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书
2014年关工委工作总结
2014/11/17 职场文书
商业门面租房协议书
2014/11/25 职场文书
校园运动会广播稿
2015/08/19 职场文书