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强制下载类型的实现代码
Apr 21 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
Oct 29 PHP
PHP __autoload()方法真的影响性能吗?
Mar 30 PHP
使用Sphinx对索引进行搜索
Jun 25 PHP
PHP静态文件生成类实例
Nov 29 PHP
php绘制一个扇形的方法
Jan 24 PHP
php使用Session和文件统计在线人数
Jul 04 PHP
PHP基于cookie与session统计网站访问量并输出显示的方法
Jan 15 PHP
深入浅析用PHP实现MVC
Mar 02 PHP
PHP7标量类型declare用法实例分析
Sep 26 PHP
Thinkphp通过一个入口文件如何区分移动端和PC端
Apr 18 PHP
PHP使用Redis长连接的方法详解
Feb 12 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
PHP array操作10个小技巧分享
2011/06/23 PHP
php地址引用(php地址引用的效率问题)
2012/03/23 PHP
PHP中4个加速、缓存扩展的区别和选用建议
2014/03/12 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
2015/12/17 PHP
XML+XSL 与 HTML 两种方案的结合
2007/04/22 Javascript
JavaScript 嵌套函数指向this对象错误的解决方法
2010/03/15 Javascript
javascript 文本框水印/占位符(watermark/placeholder)实现方法
2012/01/15 Javascript
FF IE浏览器修改标签透明度的方法
2014/01/27 Javascript
javascript删除数组元素并且数组长度减小的简单实例
2014/02/14 Javascript
按下回车键指向下一个位置的一个函数代码
2014/03/10 Javascript
基于JavaScript代码实现pc与手机之间的跳转
2015/12/23 Javascript
AngularJS指令中的绑定策略实例分析
2016/12/14 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
基于VUE.JS的移动端框架Mint UI的使用
2017/10/11 Javascript
Vue.js组件通信的几种姿势
2017/10/23 Javascript
layui table 参数设置方法
2018/08/14 Javascript
解决vue v-for 遍历循环时key值报错的问题
2018/09/06 Javascript
vue canvas绘制矩形并解决由clearRec带来的闪屏问题
2019/09/02 Javascript
JS禁用右键、禁用Ctrl+u、禁用Ctrl+s、禁用F12的实现代码
2020/12/01 Javascript
Python编程flask使用页面模版的方法
2018/12/28 Python
Python 调用 Outlook 发送邮件过程解析
2019/08/08 Python
python+selenium 脚本实现每天自动登记的思路详解
2020/03/11 Python
Python库安装速度过慢解决方案
2020/07/14 Python
Everlast官网:拳击、综合格斗和健身相关的体育用品
2020/08/03 全球购物
超市实习总结自我鉴定
2013/09/19 职场文书
连锁经营管理专业大学生求职信
2013/10/30 职场文书
中专生的个人自我评价
2013/12/11 职场文书
两年的个人工作自我评价
2014/01/10 职场文书
幼儿园中秋节活动方案2013
2014/01/29 职场文书
深入开展党的群众路线教育实践活动方案
2014/02/04 职场文书
环保专项行动方案
2014/05/12 职场文书
国际商务英语专业求职信
2014/07/08 职场文书
院党委组织查摆问题对照检查材料思想汇报2014
2014/10/08 职场文书
2014年财政局工作总结
2014/12/09 职场文书
新教师教学工作总结
2015/08/12 职场文书
修改并编译golang源码的操作步骤
2021/07/25 Golang