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边学边教》(01.开篇――准备工作)
Dec 13 PHP
PHP处理excel cvs表格的方法实例介绍
May 13 PHP
深入PHP中慎用双等于(==)的详解
Jun 06 PHP
php三维数组去重(示例代码)
Nov 26 PHP
PHP闭包实例解析
Sep 08 PHP
推荐几个开源的微信开发项目
Dec 28 PHP
php递归函数三种实现方法及如何实现数字累加
Aug 07 PHP
Zend Framework教程之Loader以及PluginLoader用法详解
Mar 09 PHP
PHP记录页面停留时间的方法
Mar 30 PHP
php实现微信扫码支付
Mar 26 PHP
基于ThinkPHP实现的日历功能实例详解
Apr 15 PHP
PHP面向对象五大原则之单一职责原则(SRP)详解
Apr 04 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
dedecms 批量提取第一张图片最为缩略图的代码(文章+软件)
2009/10/29 PHP
Yii快速入门经典教程
2015/12/28 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
2016/03/03 PHP
PHP实现实时生成并下载超大数据量的EXCEL文件详解
2017/10/23 PHP
PHP XML Expat解析器知识点总结
2019/02/15 PHP
PHP 8新特性简介
2020/08/18 PHP
js用Date对象处理时间实现思路及代码
2013/01/31 Javascript
JavaScript 命名空间 使用介绍
2013/08/29 Javascript
jquery阻止冒泡事件使用模拟事件
2013/09/06 Javascript
Javascript实现带关闭按钮的网页漂浮广告代码
2014/01/12 Javascript
搭建pomelo 开发环境
2014/06/24 Javascript
AngularJS equal比较对象实例详解
2016/09/14 Javascript
微信小程序 rpx 尺寸单位详细介绍
2016/10/13 Javascript
vue实现留言板todolist功能
2017/08/16 Javascript
vue 表单验证按钮事件交由父组件触发的方法
2018/12/17 Javascript
记一次vue-webpack项目优化实践详解
2019/02/17 Javascript
node.js中fs文件系统模块的使用方法实例详解
2020/02/13 Javascript
[03:09]显微镜下的DOTA2第一期——带你走进华丽的DOTA2世界
2014/06/20 DOTA
[52:20]DOTA2-DPC中国联赛正赛 SAG vs XGBO3 第一场 3月5日
2021/03/11 DOTA
Python实现基于PIL和tesseract的验证码识别功能示例
2018/07/11 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
2018/10/29 Python
Django Rest framework权限的详细用法
2019/07/25 Python
Python 切分数组实例解析
2019/11/07 Python
Python爬虫实现vip电影下载的示例代码
2020/04/20 Python
如何利用python读取micaps文件详解
2020/10/18 Python
python 利用matplotlib在3D空间中绘制平面的案例
2021/02/06 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
Microsoft Advertising美国:微软搜索广告
2019/05/01 全球购物
戴尔新加坡官网:Dell Singapore
2020/12/13 全球购物
JAVA软件工程师测试题
2014/07/25 面试题
经理秘书岗位职责
2013/11/14 职场文书
大学生找工作求职信
2014/07/09 职场文书
反腐倡廉影片观后感
2015/06/08 职场文书
vue实现无缝轮播效果(跑马灯)
2021/05/14 Vue.js
JavaScript中document.activeELement焦点元素介绍
2021/11/27 Javascript
关于使用Redisson订阅数问题
2022/01/18 Redis