当前位置:首页 > CMS教程 > Thinkphp > 列表

thinkphp框架使用JWTtoken的方法详解

发布:smiling 来源: PHP粉丝网  添加日期:2021-12-28 20:31:36 浏览: 评论:0 

这篇文章主要介绍了thinkphp框架使用JWTtoken的方法,结合实例形式分析了JWTtoken的功能、原理及thinkPHP使用JWTtoken实现签名验证的相关操作技巧,需要的朋友可以参考下。

本文实例讲述了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:

  1. { 
  2.  "typ": "JWT", //声明类型为jwt 
  3.  "alg": "HS256" //声明签名算法为SHA256 
  4. } 

载荷(payload)

  1. { 
  2.  "iss": "http://www.phpfensi.com", 
  3.  "aud": "http://www.phpfensi.com", 
  4.  "iat": 1525317601, 
  5.  "nbf": 1525318201, 
  6.  "exp": 1525318201, 
  7.  "data": { 
  8.   "userid": 1, 
  9.   "username": "李小龙" 
  10.  } 
  11. } 

载荷包括两部分:标准声明和其他声明。

标准声明:JWT标准规定的声明,但不是必须填写的;

标准声明字段:

接收该JWT的一方

iss: jwt签发者

sub: jwt所面向的用户

aud: 接收jwt的一方

exp: jwt的过期时间,过期时间必须要大于签发时间

nbf: 定义在什么时间之前,某个时间点后才能访问

iat: jwt的签发时间

jti: jwt的唯一身份标识,主要用来作为一次性token。

下载

composer require firebase/php-jwt

extend 下创建token类

  1. namespace Token; 
  2. use think\Controller; 
  3. use think\facade\Request; 
  4. use Firebase\JWT\JWT; 
  5. /**token类 
  6.  * Class Token 
  7.  * @package app\api\Controller 
  8.  */ 
  9. class Token 
  10. { 
  11.   /** 
  12.    * 创建 token 
  13.    * @param array $data 必填 自定义参数数组 
  14.    * @param integer $exp_time 必填 token过期时间 单位:秒 例子:7200=2小时 
  15.    * @param string $scopes 选填 token标识,请求接口的token 
  16.    * @return string 
  17.    */ 
  18.   private $TokenKey = "123456"; 
  19.   public function createToken($data="",$exp_time=0,$scopes=""){ 
  20.     //JWT标准规定的声明,但不是必须填写的; 
  21.     //iss: jwt签发者 
  22.     //sub: jwt所面向的用户 
  23.     //aud: 接收jwt的一方 
  24.     //exp: jwt的过期时间,过期时间必须要大于签发时间 
  25.     //nbf: 定义在什么时间之前,某个时间点后才能访问 
  26.     //iat: jwt的签发时间 
  27.     //jti: jwt的唯一身份标识,主要用来作为一次性token。 
  28.     //公用信息 
  29.     try { 
  30.       $key=$this->TokenKey; 
  31.       $time = time(); //当前时间 
  32.       //$token['iss']=''; //签发者 可选 
  33.       //$token['aud']=''; //接收该JWT的一方,可选 
  34.       $token['iat']=$time; //签发时间 
  35.       $token['nbf']=$time; //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用 
  36.       if($scopes){ 
  37.         $token['scopes']=$scopes; //token标识,请求接口的token 
  38.       } 
  39.       if(!$exp_time){ 
  40.         $exp_time=7200;//默认=2小时过期 
  41.       } 
  42.       $token['exp']=$time+$exp_time; //token过期时间,这里设置2个小时 
  43.       if($data){ 
  44.         $token['data']=$data; //自定义参数 
  45.       } 
  46.       $json = JWT::encode($token,$key); 
  47.       $returndata['status']="200";// 
  48.       $returndata['msg']='success'; 
  49.       $returndata['token']= $json;//返回的数据 
  50.       return $returndata; //返回信息 
  51.     }catch(\Firebase\JWT\ExpiredException $e){ //签名不正确 
  52.       $returndata['status']="104";//101=签名不正确 
  53.       $returndata['msg']=$e->getMessage(); 
  54.       $returndata['data']="";//返回的数据 
  55.       return $returndata; //返回信息 
  56.     }catch(\Exception $e) { //其他错误 
  57.       $returndata['status']="199";//199=签名不正确 
  58.       $returndata['msg']=$e->getMessage(); 
  59.       $returndata['data']="";//返回的数据 
  60.       return $returndata; //返回信息 
  61.     } 
  62.   } 
  63.   /** 
  64.    * 验证token是否有效,默认验证exp,nbf,iat时间 
  65.    * @param string $jwt 需要验证的token 
  66.    * @return string $msg 返回消息 
  67.    */ 
  68.   public function checkToken($jwt){ 
  69.     $key=$this->TokenKey; 
  70.     try { 
  71.       JWT::$leeway = 60;//当前时间减去60,把时间留点余地 
  72.       $decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应 
  73.       $arr = (array)$decoded; 
  74.       $returndata['status']="200";//200=成功 
  75.       $returndata['msg']="success";// 
  76.       $returndata['data']=$arr;//返回的数据 
  77.       return $returndata; //返回信息 
  78.     } catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确 
  79.       $returndata['status']="101";//101=签名不正确 
  80.       $returndata['msg']=$e->getMessage(); 
  81.       $returndata['data']="";//返回的数据 
  82.       //return json_encode($returndata); //返回信息 
  83.       //exit(json_encode($returndata)); 
  84.       sendResponse($returndata,401,'Unauthorized'); 
  85.     }catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用 
  86.       $returndata['status']="102"; 
  87.       $returndata['msg']=$e->getMessage(); 
  88.       $returndata['data']="";//返回的数据 
  89.       sendResponse($returndata,401,'Unauthorized'); 
  90.     }catch(\Firebase\JWT\ExpiredException $e) { // token过期 
  91.       $returndata['status']="103";//103=签名不正确 
  92.       $returndata['msg']=$e->getMessage(); 
  93.       $returndata['data']="";//返回的数据 
  94.       sendResponse($returndata,401,'Unauthorized'); 
  95.     }catch(\Exception $e) { //其他错误 
  96.       $returndata['status']="199";//199=签名不正确 
  97.       $returndata['msg']=$e->getMessage(); 
  98.       $returndata['data']="";//返回的数据 
  99.       sendResponse($returndata,401,'Unauthorized'); 
  100.     } 
  101.     //Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token 
  102.   } 

签发

  1. $jwtToken = new Token(); 
  2. $tokenData = array( 
  3.   'openid' => $user->getId(), 
  4.   'uniacid' => $_W['uniacid'], 
  5. ); 
  6. $token = $jwtToken->createToken($tokenData) 

验证

  1. if (emptyempty($_SERVER['HTTP_AUTHORIZATION'])) 
  2. { 
  3.   $res['status']="201"; 
  4.   $res['msg']="no token"; 
  5.   $res['data']="";//返回的数据 
  6.   sendResponse($res,401,'Unauthorized'); 
  7. } 
  8. $token = $_SERVER['HTTP_AUTHORIZATION']; 
  9. $jwtToken = new Token(); 
  10. $checkToken = $jwtToken->checkToken($token); 
  11. $data = (array)$checkToken['data']['data'];

Tags: thinkphp JWTtoken

分享到: