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获得用户使用的代理服务器ip即真实ip
Dec 31 PHP
PHP调用Webservice实例代码
Jul 29 PHP
深入mysql_fetch_row()与mysql_fetch_array()的区别详解
Jun 05 PHP
将word转化为swf 如同百度文库般阅读实现思路及代码
Aug 09 PHP
php后门URL的防范
Nov 12 PHP
PHP goto语句简介和使用实例
Mar 11 PHP
php根据指定位置和长度获得子字符串的方法
Mar 17 PHP
PHP滚动日志的代码实现
Jun 10 PHP
在CentOS系统上从零开始搭建WordPress博客的全流程记录
Apr 21 PHP
php连接微软MSSQL(sql server)完全攻略
Nov 27 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
Feb 11 PHP
laravel框架学习笔记之组件化开发实现方法
Feb 01 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插入排序实现代码
2013/04/04 PHP
解决phpmyadmin中缺少mysqli扩展问题的方法
2013/05/06 PHP
php实现执行某一操作时弹出确认、取消对话框
2013/12/30 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
js模拟滚动条(横向竖向)
2013/02/22 Javascript
如何获取select下拉框的值(option没有及有value属性)
2013/11/08 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
2015/04/03 Javascript
Javascript控制div属性动态变化实例分析
2015/10/08 Javascript
使用Node.js给图片加水印的方法
2016/11/15 Javascript
js实现移动端微信页面禁止字体放大
2017/02/16 Javascript
jQuery实现菜单的显示和隐藏功能示例
2018/07/24 jQuery
前后端如何实现登录token拦截校验详解
2018/09/03 Javascript
antd Upload 文件上传的示例代码
2018/12/14 Javascript
JavaScript使用ul中li标签实现删除效果
2019/04/15 Javascript
微信小程序中使用 async/await的方法实例分析
2020/05/06 Javascript
NodeJS多种创建WebSocket监听的方式(三种)
2020/06/04 NodeJs
浅析JavaScript 函数防抖和节流
2020/07/13 Javascript
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
以一个投票程序的实例来讲解Python的Django框架使用
2016/02/18 Python
python正则表达式之作业计算器
2016/03/18 Python
pycharm运行程序时在Python console窗口中运行的方法
2018/12/03 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
5行Python代码实现图像分割的步骤详解
2020/05/25 Python
Python中无限循环需要什么条件
2020/05/27 Python
Python Tornado核心及相关原理详解
2020/06/24 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
CSS3弹性盒模型开发笔记(一)
2016/04/26 HTML / CSS
使用HTML5 Canvas API中的clip()方法裁剪区域图像
2016/03/25 HTML / CSS
详解H5本地储存Web Storage
2017/07/03 HTML / CSS
canvas因为图片资源不在同一域名下而导致的跨域污染画布的解决办法
2019/01/18 HTML / CSS
canvas实现图片镜像翻转的2种方式
2020/07/22 HTML / CSS
《盲人摸象》教学反思
2014/02/16 职场文书
学生安全承诺书
2014/05/22 职场文书
群众路线教育实践活动剖析材料
2014/09/30 职场文书
学生穿着不得体检讨书
2014/10/12 职场文书
班干部竞选演讲稿(精选5篇)
2019/09/24 职场文书