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 相关文章推荐
PHP3 safe_mode 失效漏洞
Oct 09 PHP
php中突破基于HTTP_REFERER的防盗链措施(stream_context_create)
Mar 29 PHP
php读取txt文件组成SQL并插入数据库的代码(原创自Zjmainstay)
Jul 31 PHP
php中使用preg_replace函数匹配图片并加上链接的方法
Feb 06 PHP
PHP curl实现抓取302跳转后页面的示例
Jul 04 PHP
PHP SOCKET编程详解
May 22 PHP
php实现异步数据调用的方法
Dec 24 PHP
实例讲解如何在PHP的Yii框架中进行错误和异常处理
Mar 17 PHP
Zend Framework入门之环境配置及第一个Hello World示例(附demo源码下载)
Mar 21 PHP
Windows平台实现PHP连接SQL Server2008的方法
Jul 26 PHP
PHP count()函数讲解
Feb 03 PHP
layui数据表格自定义每页条数limit设置
Oct 26 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无限极分类的案例教程
2016/05/09 PHP
ThinkPHP中session函数详解
2016/09/14 PHP
php使用parse_str实现查询字符串解析到变量中的方法
2017/02/17 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
2017/07/19 PHP
javascript 跨浏览器开发经验总结(五) js 事件
2010/05/19 Javascript
JavaScript的类型简单说明
2010/09/03 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
JavaScript  event对象整理及详细介绍
2016/10/10 Javascript
Javascript实现图片懒加载插件的方法
2016/10/20 Javascript
微信小程序-消息提示框实例
2016/11/24 Javascript
Angular2里获取(input file)上传文件的内容的方法
2017/09/05 Javascript
详解如何使用webpack在vue项目中写jsx语法
2017/11/08 Javascript
javascript与PHP动态往类中添加方法对比
2018/03/21 Javascript
layui递归实现动态左侧菜单
2019/07/26 Javascript
vue监听用户输入和点击功能
2019/09/27 Javascript
jQuery擦除插件eraser使用方法详解
2020/01/11 jQuery
Nodejs在局域网配置https访问的实现方法
2020/10/17 NodeJs
vue脚手架项目创建步骤详解
2021/03/02 Vue.js
[16:04]DOTA2海涛带你玩炸弹 9月5日更新内容详解
2014/09/05 DOTA
python计算圆周长、面积、球体体积并画出圆
2014/04/08 Python
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
python采用django框架实现支付宝即时到帐接口
2016/05/17 Python
Python语言进阶知识点总结
2019/05/28 Python
python多线程分块读取文件
2019/08/29 Python
PyQt5多线程防卡死和多窗口用法的实现
2020/09/15 Python
pycharm远程连接服务器并配置python interpreter的方法
2020/12/23 Python
碧欧泉美国官网:Biotherm美国
2016/08/31 全球购物
《油菜花开了》教学反思
2014/02/22 职场文书
乡镇总工会学雷锋活动总结
2014/03/01 职场文书
年会搞笑主持词
2014/03/27 职场文书
法学专业求职信
2014/07/15 职场文书
铅球加油稿100字
2014/09/26 职场文书
大一新生检讨书
2014/10/29 职场文书
2014年幼儿园园务工作总结
2014/12/05 职场文书
Python OpenGL基本配置方式
2022/05/20 Python
Win11如何查看显卡型号 Win11查看显卡型号的方法
2022/08/14 数码科技