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中对xml读取的相关函数的介绍一
Jun 05 PHP
怎样去阅读一份php源代码
Aug 21 PHP
Ext.data.PagingMemoryProxy分页一次性读取数据的实现代码
Apr 07 PHP
PHP文件打开、关闭、写入的判断与执行代码
May 24 PHP
PHP乱码问题,UTF-8乱码常见问题小结
Apr 09 PHP
解析在PHP中使用mysqli扩展库对mysql的操作
Jul 03 PHP
php打印一个边长为N的实心和空心菱型的方法
Mar 02 PHP
四个常见html网页乱码问题及解决办法
Sep 08 PHP
php插入含有特殊符号数据的处理方法
Nov 24 PHP
thinkPHP中验证码的简单实现方法
Dec 05 PHP
php实现文件上传及头像预览功能
Jan 15 PHP
PHP使用POP3读取邮箱接收邮件的示例代码
Jul 08 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
用Simple Excel导出xls实现方法
2012/12/06 PHP
php遍历文件夹所有文件子文件夹函数代码
2013/11/27 PHP
php中session使用示例
2014/03/29 PHP
PHP基于ICU扩展intl快速实现汉字转拼音及按拼音首字母分组排序的方法
2017/05/03 PHP
PHP递归实现快速排序的方法示例
2017/12/18 PHP
javascript实现动态模态绑定grid过程代码
2014/09/22 Javascript
jQuery实现的在线答题功能
2015/04/12 Javascript
浅谈javascript中call()、apply()、bind()的用法
2015/04/20 Javascript
jQuery鼠标悬停内容动画切换效果
2017/04/27 jQuery
vuejs父子组件之间数据交互详解
2017/08/09 Javascript
Vue实现web分页组件详解
2017/11/28 Javascript
微信小程序页面上下滚动效果
2020/11/18 Javascript
解决一个微信号同时支持多个环境网页授权问题
2019/08/07 Javascript
如何通过JS实现转码与解码
2020/02/21 Javascript
javascript实现前端分页功能
2020/11/26 Javascript
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
常见python正则用法的简单实例
2016/06/21 Python
Numpy掩码式数组详解
2018/04/17 Python
python中将zip压缩包转为gz.tar的方法
2018/10/18 Python
OpenCV-Python 摄像头实时检测人脸代码实例
2019/04/30 Python
Python IDE Pycharm中的快捷键列表用法
2019/08/08 Python
win10环境下配置vscode python开发环境的教程详解
2019/10/16 Python
django自定义模板标签过程解析
2019/12/14 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
python 实现汉诺塔游戏
2020/11/28 Python
一款纯css3实现的鼠标经过按钮特效教程
2014/11/09 HTML / CSS
css3边框_动力节点Java学院整理
2017/07/11 HTML / CSS
HTML5之SVG 2D入门8—文档结构及相关元素总结
2013/01/30 HTML / CSS
全球速卖通俄罗斯站:AliExpress俄罗斯
2019/06/17 全球购物
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
SQL里面如何插入自动增长序列号字段
2012/03/29 面试题
就业推荐表自我鉴定
2013/10/29 职场文书
青年创业培训欢迎词
2014/01/10 职场文书
《雨点》教学反思
2014/02/12 职场文书
态度决定一切演讲稿
2014/05/20 职场文书
贫困生证明范文
2015/06/16 职场文书