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 相关文章推荐
如何提高MYSQL数据库的查询统计速度 select 索引应用
Apr 11 PHP
php xml实例 留言本
Mar 20 PHP
PHP 引用文件技巧
Mar 02 PHP
php数组函数序列之array_values() 获取数组元素值的函数与方法
Oct 30 PHP
探讨如何使用SimpleXML函数来加载和解析XML文档
Jun 07 PHP
使用dump函数,给php加断点测试
Jun 25 PHP
PHP获取短链接跳转后的真实地址和响应头信息的方法
Jul 25 PHP
PHP速成大法
Jan 30 PHP
PHP读取XML格式文件的方法总结
Feb 27 PHP
PHP连接MYSQL数据库的3种常用方法
Feb 27 PHP
php实现基于pdo的事务处理方法示例
Jul 21 PHP
phpStudy 2016 使用教程详解(支持PHP7)
Oct 18 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
推荐几部必看的DC动画电影
2020/03/03 欧美动漫
数据库相关问题
2006/10/09 PHP
php 文本文件的读取效率
2012/02/10 PHP
常用的php图片处理类(水印、等比缩放、固定高宽)分享
2015/06/19 PHP
laravel 创建命令行命令的图文教程
2019/10/23 PHP
ECMAScript 基础知识
2007/06/29 Javascript
nullJavascript中创建对象的五种方法实例
2013/05/07 Javascript
JavaScript输入邮箱自动提示实例代码
2014/01/13 Javascript
JS对象转换为Jquery对象示例
2014/01/26 Javascript
node.js中的fs.closeSync方法使用说明
2014/12/17 Javascript
JavaScript实现文字与图片拖拽效果的方法
2015/02/16 Javascript
jQuery实现鼠标滑过Div层背景变颜色的方法
2015/02/17 Javascript
使用AngularJS 应用访问 Android 手机的图片库
2015/03/24 Javascript
值得分享和收藏的Bootstrap学习教程
2016/05/12 Javascript
js 获取今天以及过去日期
2017/04/11 Javascript
Vue组件实例间的直接访问实现代码
2017/08/20 Javascript
Javascript防止图片拉伸的自适应处理方法
2017/12/26 Javascript
小程序跳转H5页面的方法步骤
2020/03/06 Javascript
[01:01:52]完美世界DOTA2联赛PWL S2 GXR vs Magma 第二场 11.25
2020/11/26 DOTA
Python3.2模拟实现webqq登录
2016/02/15 Python
教你用 Python 实现微信跳一跳(Mac+iOS版)
2018/01/04 Python
Python基于jieba库进行简单分词及词云功能实现方法
2018/06/16 Python
django进阶之cookie和session的使用示例
2018/08/17 Python
Pandas Shift函数的基础入门学习笔记
2018/11/16 Python
python3.8动态人脸识别的实现示例
2020/09/21 Python
OpenCV利用python来实现图像的直方图均衡化
2020/10/21 Python
用Python制作音乐海报
2021/01/26 Python
墨西哥皇宫度假村预订:Palace Resorts
2018/06/16 全球购物
化学教师自荐信范文
2013/12/28 职场文书
夫妻房产协议书的格式
2014/10/11 职场文书
全国爱牙日活动总结
2015/02/05 职场文书
英文慰问信
2015/02/14 职场文书
端午节寄语2015
2015/03/23 职场文书
js实现模拟购物商城案例
2021/05/18 Javascript
python内置进制转换函数的操作
2021/06/02 Python
Nginx 路由转发和反向代理location配置实现
2021/11/11 Servers