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调用Oracle存储过程
Oct 09 PHP
默默小谈PHP&MYSQL分页原理及实现
Jan 02 PHP
同台服务器使用缓存APC效率高于Memcached的演示代码
Feb 16 PHP
解析mysql 表中的碎片产生原因以及清理
Jun 22 PHP
学习php过程中的一些注意点的总结
Oct 25 PHP
php用header函数实现301跳转代码实例
Nov 25 PHP
php网页病毒清除类
Dec 08 PHP
php商品对比功能代码分享
Sep 24 PHP
Yii框架组件和事件行为管理详解
May 20 PHP
php网页版聊天软件实现代码
Aug 12 PHP
thinkPHP5实现数据库添加内容的方法
Oct 25 PHP
PHP设计模式之原型设计模式原理与用法分析
Apr 25 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/10/09 PHP
php去掉字符串的最后一个字符附substr()的用法
2011/03/23 PHP
php 网上商城促销设计实例代码
2012/02/17 PHP
apache中为php 设置虚拟目录
2014/12/17 PHP
PHP的mysqli_set_charset()函数讲解
2019/01/23 PHP
PHP抽象类与接口的区别详解
2019/03/21 PHP
JS继承--原型链继承和类式继承
2013/04/08 Javascript
如何将网页表格内容导入excel
2014/02/18 Javascript
javascript实现输出指定行数正方形图案的方法
2015/08/03 Javascript
早该知道的7个JavaScript技巧
2016/06/21 Javascript
关于javascript中限定时间内防止按钮重复点击的思路详解
2016/08/16 Javascript
Jquery组件easyUi实现表单验证示例
2016/08/23 Javascript
JS与jQuery实现隔行变色的方法
2016/09/09 Javascript
React+react-dropzone+node.js实现图片上传的示例代码
2017/08/23 Javascript
微信小程序云开发(数据库)详解
2019/05/17 Javascript
微信小程序new Date()方法失效问题解决方法
2019/07/29 Javascript
python字符类型的一些方法小结
2016/05/16 Python
python和shell监控linux服务器的详细代码
2018/06/22 Python
Python爬虫实战之12306抢票开源
2019/01/24 Python
python文档字符串(函数使用说明)使用详解
2019/07/30 Python
使用Django搭建web服务器的例子(最最正确的方式)
2019/08/29 Python
Python获取时间戳代码实例
2019/09/24 Python
TensorFlow学习之分布式的TensorFlow运行环境
2020/02/05 Python
Python实现验证码识别
2020/06/15 Python
如何利用pycharm进行代码更新比较
2020/11/04 Python
python编写扎金花小程序的实例代码
2021/02/23 Python
简单叙述一下MYSQL的优化
2016/05/09 面试题
畜牧兽医本科生个人的自我评价
2013/10/11 职场文书
应届毕业生自我鉴定范文
2013/12/27 职场文书
小学毕业寄语大全
2014/04/03 职场文书
优秀学生干部先进事迹材料
2014/05/26 职场文书
新学期标语
2014/06/30 职场文书
大专应届毕业生求职信
2014/07/15 职场文书
学校元旦晚会开场白
2015/05/29 职场文书
高中班主任工作总结(范文)
2019/08/20 职场文书
Python制作一个随机抽奖小工具的实现
2021/07/07 Python