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
实用函数10
Nov 08 PHP
PHP set_time_limit(0)长连接的实现分析
Mar 02 PHP
PHP程序员最常犯的11个MySQL错误小结
Nov 20 PHP
php中一个完整表单处理实现代码
Nov 10 PHP
基于MySQL体系结构的分析
May 02 PHP
关于使用coreseek并为其做分页的介绍
Jun 21 PHP
php中字符查找函数strpos、strrchr与strpbrk用法
Nov 18 PHP
php备份数据库类分享
Apr 14 PHP
教大家制作简单的php日历
Nov 17 PHP
Zend Framework教程之模型Model基本规则和使用方法
Mar 04 PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
Mar 29 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.MVC的模板标签系统(四)
2006/09/05 PHP
php miniBB中文乱码问题解决方法
2008/11/25 PHP
PHP获取短链接跳转后的真实地址和响应头信息的方法
2014/07/25 PHP
PHP文件上传类实例详解
2016/04/08 PHP
php 中htmlentities导致中文无法查询问题
2018/09/10 PHP
Yii框架分页技术实例分析
2019/08/30 PHP
图片连续滚动代码[兼容IE/firefox]
2009/06/11 Javascript
juqery 学习之五 文档处理 包裹、替换、删除、复制
2011/02/11 Javascript
js 针对html DOM元素操作等经验累积
2014/03/11 Javascript
JavaScript生成SQL查询表单的方法
2015/08/13 Javascript
Backbone.js框架中简单的View视图编写学习笔记
2016/02/14 Javascript
基于Javascript实现文件实时加载进度的方法
2016/10/12 Javascript
js移动端图片压缩上传功能
2020/08/18 Javascript
vue的状态管理模式vuex
2017/11/30 Javascript
angularjs获取到My97DatePicker选中的值方法
2018/10/02 Javascript
layui的select联动实现代码
2019/09/28 Javascript
解决谷歌搜索技术文章时打不开网页问题的python脚本
2013/02/10 Python
Python彩色化Linux的命令行终端界面的代码实例分享
2016/07/02 Python
Python获取当前路径实现代码
2017/05/08 Python
VScode编写第一个Python程序HelloWorld步骤
2018/04/06 Python
Python3实现的判断环形链表算法示例
2019/03/07 Python
python面向对象法实现图书管理系统
2019/04/19 Python
python3实现猜数字游戏
2020/12/07 Python
使用 python pyautogui实现鼠标键盘控制功能
2019/08/04 Python
pytorch自定义二值化网络层方式
2020/01/07 Python
python计算波峰波谷值的方法(极值点)
2020/02/18 Python
Python 用__new__方法实现单例的操作
2020/12/11 Python
Python实现微信表情包炸群功能
2021/01/28 Python
美国专业消费电子及摄影器材网站:B&H Photo Video
2019/12/18 全球购物
优秀技术工人先进材料
2014/02/17 职场文书
计算机通信专业推荐信
2014/02/22 职场文书
学校机关党总支领导班子整改工作方案
2014/10/26 职场文书
技术员个人工作总结
2015/03/03 职场文书
《小蝌蚪找妈妈》教学反思
2016/02/23 职场文书
浅谈自定义校验注解ConstraintValidator
2021/06/30 Java/Android
mysql如何查询连续记录
2022/05/11 MySQL