thinkphp框架使用JWTtoken的方法详解


Posted in PHP onOctober 10, 2019

本文实例讲述了thinkphp框架使用JWTtoken的方法。分享给大家供大家参考,具体如下:

简介

一:JWT介绍:全称JSON Web Token,基于JSON的开放标准((RFC 7519) ,以token的方式代替传统的Cookie-Session模式,用于各服务器、客户端传递信息签名验证。

二:JWT优点:

1:服务端不需要保存传统会话信息,没有跨域传输问题,减小服务器开销。

2:jwt构成简单,占用很少的字节,便于传输。

3:json格式通用,不同语言之间都可以使用。

三:JWT组成

1:jwt由三部分组成:

     头部(header)
     载荷(payload) 包含一些定义信息和自定义信息
     签证(signature)

2:具体构成:

header:

{
 "typ": "JWT", //声明类型为jwt
 "alg": "HS256" //声明签名算法为SHA256
}

载荷(payload)

{
 "iss": "http://www.helloweba.net",
 "aud": "http://www.helloweba.net",
 "iat": 1525317601,
 "nbf": 1525318201,
 "exp": 1525318201,
 "data": {
  "userid": 1,
  "username": "李小龙"
 }
}

载荷包括两部分:标准声明和其他声明。

标准声明:JWT标准规定的声明,但不是必须填写的;

标准声明字段:

接收该JWT的一方

iss: jwt签发者

sub: jwt所面向的用户

aud: 接收jwt的一方

exp: jwt的过期时间,过期时间必须要大于签发时间

nbf: 定义在什么时间之前,某个时间点后才能访问

iat: jwt的签发时间

jti: jwt的唯一身份标识,主要用来作为一次性token。

下载

composer require firebase/php-jwt

extend 下创建token类

namespace Token;
use think\Controller;
use think\facade\Request;
use Firebase\JWT\JWT;
/**token类
 * Class Token
 * @package app\api\Controller
 */
class Token
{
  /**
   * 创建 token
   * @param array $data 必填 自定义参数数组
   * @param integer $exp_time 必填 token过期时间 单位:秒 例子:7200=2小时
   * @param string $scopes 选填 token标识,请求接口的token
   * @return string
   */
  private $TokenKey = "123456";
  public function createToken($data="",$exp_time=0,$scopes=""){
    //JWT标准规定的声明,但不是必须填写的;
    //iss: jwt签发者
    //sub: jwt所面向的用户
    //aud: 接收jwt的一方
    //exp: jwt的过期时间,过期时间必须要大于签发时间
    //nbf: 定义在什么时间之前,某个时间点后才能访问
    //iat: jwt的签发时间
    //jti: jwt的唯一身份标识,主要用来作为一次性token。
    //公用信息
    try {
      $key=$this->TokenKey;
      $time = time(); //当前时间
      //$token['iss']=''; //签发者 可选
      //$token['aud']=''; //接收该JWT的一方,可选
      $token['iat']=$time; //签发时间
      $token['nbf']=$time; //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
      if($scopes){
        $token['scopes']=$scopes; //token标识,请求接口的token
      }
      if(!$exp_time){
        $exp_time=7200;//默认=2小时过期
      }
      $token['exp']=$time+$exp_time; //token过期时间,这里设置2个小时
      if($data){
        $token['data']=$data; //自定义参数
      }
      $json = JWT::encode($token,$key);
      $returndata['status']="200";//
      $returndata['msg']='success';
      $returndata['token']= $json;//返回的数据
      return $returndata; //返回信息
    }catch(\Firebase\JWT\ExpiredException $e){ //签名不正确
      $returndata['status']="104";//101=签名不正确
      $returndata['msg']=$e->getMessage();
      $returndata['data']="";//返回的数据
      return $returndata; //返回信息
    }catch(\Exception $e) { //其他错误
      $returndata['status']="199";//199=签名不正确
      $returndata['msg']=$e->getMessage();
      $returndata['data']="";//返回的数据
      return $returndata; //返回信息
    }
  }
  /**
   * 验证token是否有效,默认验证exp,nbf,iat时间
   * @param string $jwt 需要验证的token
   * @return string $msg 返回消息
   */
  public function checkToken($jwt){
    $key=$this->TokenKey;
    try {
      JWT::$leeway = 60;//当前时间减去60,把时间留点余地
      $decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
      $arr = (array)$decoded;
      $returndata['status']="200";//200=成功
      $returndata['msg']="success";//
      $returndata['data']=$arr;//返回的数据
      return $returndata; //返回信息
    } catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
      $returndata['status']="101";//101=签名不正确
      $returndata['msg']=$e->getMessage();
      $returndata['data']="";//返回的数据
      //return json_encode($returndata); //返回信息
      //exit(json_encode($returndata));
      sendResponse($returndata,401,'Unauthorized');
    }catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
      $returndata['status']="102";
      $returndata['msg']=$e->getMessage();
      $returndata['data']="";//返回的数据
      sendResponse($returndata,401,'Unauthorized');
    }catch(\Firebase\JWT\ExpiredException $e) { // token过期
      $returndata['status']="103";//103=签名不正确
      $returndata['msg']=$e->getMessage();
      $returndata['data']="";//返回的数据
      sendResponse($returndata,401,'Unauthorized');
    }catch(\Exception $e) { //其他错误
      $returndata['status']="199";//199=签名不正确
      $returndata['msg']=$e->getMessage();
      $returndata['data']="";//返回的数据
      sendResponse($returndata,401,'Unauthorized');
    }
    //Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
  }

签发

$jwtToken = new Token();
$tokenData = array(
  'openid' => $user->getId(),
  'uniacid' => $_W['uniacid'],
);
$token = $jwtToken->createToken($tokenData)

验证

if (empty($_SERVER['HTTP_AUTHORIZATION']))
{
  $res['status']="201";
  $res['msg']="no token";
  $res['data']="";//返回的数据
  sendResponse($res,401,'Unauthorized');
}
$token = $_SERVER['HTTP_AUTHORIZATION'];
$jwtToken = new Token();
$checkToken = $jwtToken->checkToken($token);
$data = (array)$checkToken['data']['data'];

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
简单的PHP留言本实例代码
May 09 PHP
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
Jul 04 PHP
PHPThumb PHP 图片缩略图库
Mar 11 PHP
php字符串分割函数explode的实例代码
Feb 07 PHP
分享一段php获取linux服务器状态的代码
May 27 PHP
ThinkPHP模板替换与系统常量及应用实例教程
Aug 22 PHP
基于GD2图形库的PHP生成图片缩略图类代码分享
Feb 08 PHP
用php来限制每个ip每天浏览页面数量的实现思路
Feb 24 PHP
php获取本周星期一具体日期的方法
Apr 20 PHP
使用PHP进行微信公众平台开发的示例
Aug 21 PHP
php框架CodeIgniter主从数据库配置方法分析
May 25 PHP
Laravel开启跨域请求的方法
Oct 13 PHP
Laravel 对某一列进行筛选然后求和sum()的例子
Oct 10 #PHP
asp.net和php的区别点总结
Oct 10 #PHP
解决laravel groupBy 对查询结果进行分组出现的问题
Oct 09 #PHP
PHP之多条件混合筛选功能的实现方法
Oct 09 #PHP
laravel实现按月或天或小时统计mysql数据的方法
Oct 09 #PHP
laravel5.5添加echarts实现画图功能的方法
Oct 09 #PHP
使用laravel和ECharts实现折线图效果的例子
Oct 09 #PHP
You might like
生成静态页面的PHP类
2006/07/15 PHP
基于asp+ajax和数据库驱动的二级联动菜单
2010/05/06 PHP
php遍历文件夹所有文件子文件夹函数代码
2013/11/27 PHP
大家须知简单的php性能优化注意点
2016/01/04 PHP
PHP session垃圾回收机制实例分析
2019/06/28 PHP
php中Swoole的热更新实现代码实例
2021/03/04 PHP
JS 常用校验函数
2009/03/26 Javascript
checkbox 复选框不能为空
2009/07/11 Javascript
LazyForm jQuery plugin 定制您的CheckBox Radio和Select
2009/10/24 Javascript
javascript克隆对象深度介绍
2012/11/20 Javascript
jQuery学习之prop和attr的区别示例介绍
2013/11/15 Javascript
JavaScript跨域方法汇总
2014/10/16 Javascript
javascript结合fileReader 实现上传图片
2015/01/30 Javascript
JavaScript面向对象的实现方法小结
2015/04/14 Javascript
JS判断是否在微信浏览器打开的简单实例(推荐)
2016/08/24 Javascript
在js中实现邮箱格式的验证方法(推荐)
2016/10/24 Javascript
Node.js复制文件的方法示例
2016/12/29 Javascript
完美解决axios跨域请求出错的问题
2018/02/05 Javascript
jQuery实现定时隐藏对话框的方法分析
2018/02/12 jQuery
vue 详情跳转至列表页实现列表页缓存
2019/03/27 Javascript
layui上传图片到服务器的非项目目录下的方法
2019/09/26 Javascript
Python生成器(Generator)详解
2015/04/13 Python
python去除所有html标签的方法
2015/05/05 Python
Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)
2019/05/13 Python
python 使用opencv 把视频分割成图片示例
2019/12/12 Python
Python能做什么
2020/06/02 Python
使用python matploblib库绘制准确率,损失率折线图
2020/06/16 Python
查看keras的默认backend实现方式
2020/06/19 Python
英国剑桥包官网:The Cambridge Satchel Company
2016/08/01 全球购物
波兰家具和室内装饰品购物网站:Vivre
2018/04/10 全球购物
JD Sports澳洲官网:英国领先的运动鞋和运动时尚零售商
2020/02/15 全球购物
中软国际Java程序员笔试题
2014/07/19 面试题
大学同学聚会邀请函
2014/01/29 职场文书
国家励志奖学金个人先进事迹材料
2014/05/04 职场文书
法人委托书
2014/07/31 职场文书
2015年学校精神文明工作总结
2015/05/27 职场文书