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 相关文章推荐
用Flash图形化数据(一)
Oct 09 PHP
php5编程中的异常处理详细方法介绍
Jul 29 PHP
phpmyadmin 常用选项设置详解版
Mar 07 PHP
php 高性能书写
Dec 11 PHP
详谈PHP文件目录基础操作
Nov 11 PHP
教你在PHPStorm中配置Xdebug
Jul 27 PHP
Yii2中简单的场景使用介绍
Jun 02 PHP
php生成毫秒时间戳的实例讲解
Sep 22 PHP
PHP读取并输出XML文件数据的简单实现方法
Dec 22 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
Laravel推荐使用的十个辅助函数
May 10 PHP
调试php程序的简单步骤
Oct 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
PHP针对JSON操作实例分析
2015/01/12 PHP
javascript offsetX与layerX区别
2010/03/12 Javascript
jquery选择器(常用选择器说明)
2010/09/28 Javascript
FireFox下XML对象转化成字符串的解决方法
2011/12/09 Javascript
javascript 基础篇2 数据类型,语句,函数
2012/03/14 Javascript
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
2012/10/11 Javascript
div拖拽插件——JQ.MoveBox.js(自制JQ插件)
2013/05/17 Javascript
Jquery多选下拉列表插件jquery multiselect功能介绍及使用
2013/05/24 Javascript
js showModalDialog参数的使用详解
2014/01/07 Javascript
Javascript冒泡排序算法详解
2014/12/03 Javascript
30个经典的jQuery代码开发技巧
2014/12/15 Javascript
JavaScript比较两个对象是否相等的方法
2015/02/06 Javascript
JavaScript操作Oracle数据库示例
2015/03/06 Javascript
jQuery使用empty()方法删除元素及其所有子元素的方法
2015/03/26 Javascript
微信开发 使用picker封装省市区三级联动模板
2016/10/28 Javascript
使用JS和canvas实现gif动图的停止和播放代码
2017/09/01 Javascript
pace.js和NProgress.js两个加载进度插件的一点小总结
2018/01/31 Javascript
JS 正则表达式验证密码、邮箱格式的实例代码
2018/10/28 Javascript
解决vue侦听器watch,调用this时出现undefined的问题
2020/10/30 Javascript
我就是这样学习Python中的列表
2019/06/02 Python
Python 合并多个TXT文件并统计词频的实现
2019/08/23 Python
python如何保证输入键入数字的方法
2019/08/23 Python
用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)
2020/06/04 Python
canvas中普通动效与粒子动效的实现代码示例
2019/01/03 HTML / CSS
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
销售类个人求职信范文
2013/09/25 职场文书
银行开业庆典方案
2014/02/06 职场文书
房屋租赁协议书
2014/04/10 职场文书
委托证明书
2014/09/17 职场文书
县政府领导班子四风问题对照检查材料思想汇报
2014/09/26 职场文书
小学生成绩单评语
2014/12/31 职场文书
学生党支部工作总结2015
2015/05/26 职场文书
培训学校2015年度工作总结
2015/07/20 职场文书
《家》读后感:万惜拯救,冷暖自知
2019/09/25 职场文书
SpringCloud之@FeignClient()注解的使用方式
2021/09/25 Java/Android
python实现简单石头剪刀布游戏
2021/10/24 Python