原文鏈接:https://www.jb51.net/article/146790.htm
機制:

代碼如下:
<?php
/**
* PHP實現jwt
*/
class
Jwt {
//頭部
private
static
$header
=
array
(
'alg'
=>
'HS256'
,
//生成signature的算法
'typ'
=>
'JWT'
//類型
);
//使用HMAC生成信息摘要時所使用的密鑰
private
static
$key
=
'123456'
;
/**
* 獲取jwt token
* @param array $payload jwt載荷 格式如下非必須
* [
* 'iss'=>'jwt_admin', //該JWT的簽發者
* 'iat'=>time(), //簽發時間
* 'exp'=>time()+7200, //過期時間
* 'nbf'=>time()+60, //該時間之前不接收處理該Token
* 'sub'=>'www.admin.com', //面向的用戶
* 'jti'=>md5(uniqid('JWT').time()) //該Token唯一標識
* ]
* @return bool|string
*/
public
static
function
getToken(
array
$payload
)
{
if
(
is_array
(
$payload
))
{
$base64header
=self::base64UrlEncode(json_encode(self::
$header
,JSON_UNESCAPED_UNICODE));
$base64payload
=self::base64UrlEncode(json_encode(
$payload
,JSON_UNESCAPED_UNICODE));
$token
=
$base64header
.
'.'
.
$base64payload
.
'.'
.self::signature(
$base64header
.
'.'
.
$base64payload
,self::
$key
,self::
$header
[
'alg'
]);
return
$token
;
}
else
{
return
false;
}
}
/**
* 驗證token是否有效,默認驗證exp,nbf,iat時間
* @param string $Token 需要驗證的token
* @return bool|string
*/
public
static
function
verifyToken(string
$Token
)
{
$tokens
=
explode
(
'.'
,
$Token
);
if
(
count
(
$tokens
) != 3)
return
false;
list(
$base64header
,
$base64payload
,
$sign
) =
$tokens
;
//獲取jwt算法
$base64decodeheader
= json_decode(self::base64UrlDecode(
$base64header
), JSON_OBJECT_AS_ARRAY);
if
(
empty
(
$base64decodeheader
[
'alg'
]))
return
false;
//簽名驗證
if
(self::signature(
$base64header
.
'.'
.
$base64payload
, self::
$key
,
$base64decodeheader
[
'alg'
]) !==
$sign
)
return
false;
$payload
= json_decode(self::base64UrlDecode(
$base64payload
), JSON_OBJECT_AS_ARRAY);
//簽發時間大於當前服務器時間驗證失敗
if
(isset(
$payload
[
'iat'
]) &&
$payload
[
'iat'
] > time())
return
false;
//過期時間小宇當前服務器時間驗證失敗
if
(isset(
$payload
[
'exp'
]) &&
$payload
[
'exp'
] < time())
return
false;
//該nbf時間之前不接收處理該Token
if
(isset(
$payload
[
'nbf'
]) &&
$payload
[
'nbf'
] > time())
return
false;
return
$payload
;
}
/**
* base64UrlEncode https://jwt.io/ 中base64UrlEncode編碼實現
* @param string $input 需要編碼的字符串
* @return string
*/
private
static
function
base64UrlEncode(string
$input
)
{
return
str_replace
(
'='
,
''
,
strtr
(
base64_encode
(
$input
),
'+/'
,
'-_'
));
}
/**
* base64UrlEncode https://jwt.io/ 中base64UrlEncode解碼實現
* @param string $input 需要解碼的字符串
* @return bool|string
*/
private
static
function
base64UrlDecode(string
$input
)
{
$remainder
=
strlen
(
$input
) % 4;
if
(
$remainder
) {
$addlen
= 4 -
$remainder
;
$input
.=
str_repeat
(
'='
,
$addlen
);
}
return
base64_decode
(
strtr
(
$input
,
'-_'
,
'+/'
));
}
/**
* HMACSHA256簽名 https://jwt.io/ 中HMACSHA256簽名實現
* @param string $input 為base64UrlEncode(header).".".base64UrlEncode(payload)
* @param string $key
* @param string $alg 算法方式
* @return mixed
*/
private
static
function
signature(string
$input
, string
$key
, string
$alg
=
'HS256'
)
{
$alg_config
=
array
(
'HS256'
=>
'sha256'
);
return
self::base64UrlEncode(hash_hmac(
$alg_config
[
$alg
],
$input
,
$key
,true));
}
}
//測試和官網是否匹配begin
$payload
=
array
(
'sub'
=>
'1234567890'
,
'name'
=>
'John Doe'
,
'iat'
=>1516239022);
$jwt
=
new
Jwt;
$token
=
$jwt
->getToken(
$payload
);
echo
"<pre>"
;
echo
$token
;
//對token進行驗證簽名
$getPayload
=
$jwt
->verifyToken(
$token
);
echo
"<br><br>"
;
var_dump(
$getPayload
);
echo
"<br><br>"
;
//測試和官網是否匹配end
//自己使用測試begin
$payload_test
=
array
(
'iss'
=>
'admin'
,
'iat'
=>time(),
'exp'
=>time()+7200,
'nbf'
=>time(),
'sub'
=>
'www.admin.com'
,
'jti'
=>md5(uniqid(
'JWT'
).time()));;
$token_test
=Jwt::getToken(
$payload_test
);
echo
"<pre>"
;
echo
$token_test
;
//對token進行驗證簽名
$getPayload_test
=Jwt::verifyToken(
$token_test
);
echo
"<br><br>"
;
var_dump(
$getPayload_test
);
echo
"<br><br>"
;
//自己使用時候end