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 相关文章推荐
Win9x/ME下Apache+PHP安装配置
Oct 09 PHP
简单的PHP留言本实例代码
May 09 PHP
30 个很棒的PHP开源CMS内容管理系统小结
Oct 14 PHP
PHP跨时区(UTC时间)应用解决方案
Jan 11 PHP
PHP运行模式的深入理解
Jun 03 PHP
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
Jun 14 PHP
destoon网站转移服务器后搜索汉字出现乱码的解决方法
Jun 21 PHP
php中文验证码实现方法
Jun 18 PHP
简介WordPress中用于获取首页和站点链接的PHP函数
Dec 17 PHP
PHP载入图像imagecreatefrom_gif_jpeg_png系列函数用法分析
Nov 14 PHP
PHP使用HTML5 FormData对象提交表单操作示例
Jul 02 PHP
laravel 解决多库下的DB::transaction()事务失效问题
Oct 21 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新手上路(十四)
2006/10/09 PHP
php Smarty模板生成html文档的方法
2010/04/12 PHP
PHP实现找出链表中环的入口节点
2018/01/16 PHP
php模式设计之观察者模式应用实例分析
2019/09/25 PHP
关于js获取radio和select的属性并控制的代码
2011/05/12 Javascript
js获取指定日期前后的日期代码
2013/08/20 Javascript
JavaScript实现模仿桌面窗口的方法
2015/07/18 Javascript
谈谈AngularJs中的隐藏和显示
2015/12/09 Javascript
javascript实现简单的全选和反选功能
2016/01/05 Javascript
jQuery+css实现的tab切换标签(兼容各浏览器)
2016/01/28 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
javascript 中的继承实例详解
2017/05/05 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
nodejs body-parser 解析post数据实例
2017/07/26 NodeJs
如何选择适合你的JavaScript框架
2017/11/20 Javascript
详解PHP后期静态绑定分析与应用
2018/03/21 Javascript
vue项目中mock.js的使用及基本用法
2019/05/22 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
JS实现图片懒加载(lazyload)过程详解
2020/04/02 Javascript
[12:51]71泪洒现场!是DOTA2让经典重现
2014/03/24 DOTA
[01:02:18]VGJ.S vs infamous Supermajor 败者组 BO3 第一场 6.4
2018/06/05 DOTA
python输入整条数据分割存入数组的方法
2018/11/13 Python
Python使用微信itchat接口实现查看自己微信的信息功能详解
2019/08/22 Python
Django实现基于类的分页功能
2019/10/31 Python
Python selenium 自动化脚本打包成一个exe文件(推荐)
2020/01/14 Python
Python爬虫库BeautifulSoup的介绍与简单使用实例
2020/01/25 Python
python matplotlib.pyplot.plot()参数用法
2020/04/14 Python
Python读取Excel一列并计算所有对象出现次数的方法
2020/09/04 Python
CSS3区域模块region相关编写示例
2015/08/28 HTML / CSS
HTML5中meta属性的使用方法
2016/02/29 HTML / CSS
HTML5+WebSocket实现多文件同时上传的实例
2016/12/29 HTML / CSS
加拿大高尔夫超市:Golf Town
2018/01/12 全球购物
优秀导游先进事迹材料
2014/01/25 职场文书
环保证明
2015/06/23 职场文书
写作技巧:怎样写好一份优秀工作总结?
2019/08/14 职场文书
dubbo服务整合zipkin详解
2021/07/26 Java/Android