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下清空字符串中的HTML标签的代码
Sep 06 PHP
谈谈关于php的优点与缺点
Apr 11 PHP
初识Laravel
Oct 30 PHP
php取得字符串首字母的方法
Mar 25 PHP
smarty高级特性之对象的使用方法
Dec 25 PHP
Yii2.0中的COOKIE和SESSION用法
Aug 12 PHP
PHP封装的完整分页类示例
Aug 21 PHP
PHP实现数据四舍五入的方法小结【4种方法】
Mar 27 PHP
PHP写API输出的时用echo的原因详解
Apr 28 PHP
php 策略模式原理与应用深入理解
Sep 25 PHP
tp5递归 无限级分类详解
Oct 18 PHP
php post换行的方法
Feb 03 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
DC四月将推出百页特刊漫画 纪念小丑诞生80周年
2020/04/09 欧美动漫
探讨:如何通过stats命令分析Memcached的内部状态
2013/06/14 PHP
PHP array_shift()用法实例分析
2019/01/07 PHP
Laravel 实现数据软删除功能
2019/08/21 PHP
iframe 自适应高度[在IE6 IE7 FF下测试通过]
2009/04/13 Javascript
高性能WEB开发 flush让页面分块,逐步呈现 flush让页面分块,逐步呈现
2010/06/19 Javascript
动感效果的TAB选项卡jquery 插件
2011/07/09 Javascript
JS获取当前日期和时间的简单实例
2013/11/19 Javascript
jQuery实现购物车计算价格功能的方法
2015/03/25 Javascript
jQuery弹出层后禁用底部滚动条(移动端关闭回到原位置)
2016/08/29 Javascript
老生常谈原生JS执行环境与作用域
2016/11/22 Javascript
最常见的左侧分类菜单栏jQuery实现代码
2016/11/28 Javascript
从零开始做一个pagination分页组件
2017/03/15 Javascript
Javascript es7中比较实用的两个方法示例
2017/07/21 Javascript
gulp教程_从入门到项目中快速上手使用方法
2017/09/14 Javascript
微信小程序使用modal组件弹出对话框功能示例
2017/11/29 Javascript
vue请求本地自己编写的json文件的方法
2019/04/25 Javascript
基于vue-cli3创建libs库的实现方法
2019/12/04 Javascript
[41:11]完美世界DOTA2联赛PWL S2 Inki vs Magma 第一场 11.22
2020/11/24 DOTA
如何利用Fabric自动化你的任务
2016/10/20 Python
Python字符串格式化的方法(两种)
2017/09/19 Python
Python之多线程爬虫抓取网页图片的示例代码
2018/01/10 Python
使用python绘制二维图形示例
2019/11/22 Python
使用 Python 在京东上抢口罩的思路详解
2020/02/27 Python
python实现飞机大战项目
2020/03/11 Python
Python descriptor(描述符)的实现
2020/11/15 Python
英国外籍人士的在线超市:British Corner Shop
2019/06/03 全球购物
英国美术用品购物网站:Cass Art
2019/10/08 全球购物
高二历史教学反思
2014/01/25 职场文书
2014学校庆三八妇女节活动总结
2014/03/01 职场文书
树转促学习心得体会
2014/09/10 职场文书
总经理岗位职责
2015/02/04 职场文书
医务人员医德考评自我评价
2015/03/03 职场文书
酒店办公室主任岗位职责
2015/04/01 职场文书
2015年乡镇环保工作总结
2015/04/22 职场文书
springboot集成springCloud中gateway时启动报错的解决
2021/07/16 Java/Android