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中的时间处理
Oct 09 PHP
Discuz! Passport 通行证整合
Mar 27 PHP
让PHP以ROOT权限执行系统命令的方法
Feb 10 PHP
php中修改浏览器的User-Agent来伪装你的浏览器和操作系统
Jul 29 PHP
PHP中全面阻止SQL注入式攻击分析小结
Jan 30 PHP
php实现爬取和分析知乎用户数据
Jan 26 PHP
php Session无效分析资料整理
Nov 29 PHP
Laravel 中使用 Vue.js 实现基于 Ajax 的表单提交错误验证操作
Jun 30 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
Sep 20 PHP
PHP生成随机数的方法总结
Mar 01 PHP
tp5.0框架隐藏index.php入口文件及模块和控制器的方法分析
Feb 11 PHP
php修改word的实例方法
Nov 17 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 url地址栏传中文乱码解决方法集合
2010/06/25 PHP
php中的注释、变量、数组、常量、函数应用介绍
2012/11/16 PHP
php获取数组中重复数据的两种方法
2013/06/28 PHP
详解php伪造Referer请求反盗链资源
2019/01/24 PHP
用javascript获得地址栏参数的两种方法
2006/11/08 Javascript
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
2010/03/24 Javascript
THREE.JS入门教程(3)着色器-下
2013/01/24 Javascript
js实现带搜索功能的下拉框实时搜索实时匹配
2013/11/05 Javascript
js 弹出框只弹一次(二次修改之后的)
2013/11/26 Javascript
jQuery对下拉框,单选框,多选框的操作
2014/02/21 Javascript
node.js中的events.emitter.listeners方法使用说明
2014/12/10 Javascript
JavaScript 学习笔记之数据类型
2015/01/14 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
JQuery解析XML数据的几个简单实例
2016/05/18 Javascript
javascript实现日期三级联动下拉框选择菜单
2020/12/03 Javascript
详解利用Angular实现多团队模块化SPA开发框架
2017/11/27 Javascript
JavaScript运行机制实例分析
2020/04/11 Javascript
JS端基于download.js实现图片、视频时直接下载而不是打开预览
2020/05/09 Javascript
[54:10]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
python中的__slots__使用示例
2015/02/26 Python
python中defaultdict的用法详解
2017/06/07 Python
利用Python如何实现一个小说网站雏形
2018/11/23 Python
详解Python计算机视觉 图像扭曲(仿射扭曲)
2019/03/27 Python
使用CSS3制作一个简单的进度条(demo)
2017/05/23 HTML / CSS
Qoo10马来西亚:全球时尚和引领潮流的购物市场
2016/08/25 全球购物
业绩考核岗位职责
2014/02/01 职场文书
党员干部承诺书范文
2014/03/25 职场文书
安全在我心中演讲稿
2014/09/01 职场文书
2014村党支部书记党建工作汇报材料
2014/11/02 职场文书
2014年幼儿园教研工作总结
2014/12/04 职场文书
继续教育个人总结
2015/03/03 职场文书
会计工作态度自我评价
2015/03/06 职场文书
心术观后感
2015/06/11 职场文书
2016学习全国教书育人楷模先进事迹心得体会
2016/01/21 职场文书
一次SQL查询优化原理分析(900W+数据从17s到300ms)
2022/06/10 SQL Server
使用python生成大量数据写入es数据库并查询操作(2)
2022/09/23 Python