本文实例讲述了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
3
4
|
{
"typ" : "JWT" , //声明类型为jwt
"alg" : "HS256" //声明签名算法为SHA256
}
|
载荷(payload)
1
2
3
4
5
6
7
8
9
10
11
|
{
"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。
下载
1
|
composer require firebase /php-jwt
|
extend 下创建token类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
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
}
|
签发
1
2
3
4
5
6
|
$jwtToken = new Token();
$tokenData = array (
'openid' => $user ->getId(),
'uniacid' => $_W [ 'uniacid' ],
);
$token = $jwtToken ->createToken( $tokenData )
|
验证
1
2
3
4
5
6
7
8
9
10
11
|
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程序设计有所帮助。
原文链接:https://blog.csdn.net/flysnownet/article/details/90260826