当前位置:首页 > CN2资讯 > 正文内容

php firebase/php-jwt token验证firebase/php-jwt

2天前CN2资讯


一: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。

其他声明:自己定义的字段,因为这部分是可以解开的,建议不要加入敏感信息,这里的data就是我自己定义的声明

 

最终是这样的:

 

 

 

三部分分别以逗号隔开

四:使用:PHP有很多jwt包,包括比如:lcobucci/jwt,我这里使用firebase。可以从 ​​git地址​​ 下载

1:把代码拉取下来



composer require firebase/php-jwt


2:服务端签发Token



?php
use \Firebase\JWT\JWT; //导入JWT
class MainController extends Controller
{

//签发Token
public function lssue()
{
$key = '344'; //key
$time = time(); //当前时间
$token = [
'iss' => 'http://www.helloweba.net', //签发者 可选
'aud' => 'http://www.helloweba.net', //接收该JWT的一方,可选
'iat' => $time, //签发时间
'nbf' => $time , //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
'exp' => $time+7200, //过期时间,这里设置2个小时
'data' => [ //自定义信息,不要定义敏感信息
'userid' => 1,
'username' => '李小龙'
]
];
echo JWT::encode($token, $key); //输出Token
}
}
————————————————


3:解析Token,为了演示,这里直接写



<?php
use \Firebase\JWT\JWT; //导入JWT
class MainController extends Controller
{

public function verification()
{
$key = '344'; //key要和签发的时候一样

$jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC93d3cuaGVsbG93ZWJhLm5ldCIsImF1ZCI6Imh0dHA6XC9cL3d3dy5oZWxsb3dlYmEubmV0IiwiaWF0IjoxNTI1MzQwMzE3LCJuYmYiOjE1MjUzNDAzMTcsImV4cCI6MTUyNTM0NzUxNywiZGF0YSI6eyJ1c2VyaWQiOjEsInVzZXJuYW1lIjoiXHU2NzRlXHU1YzBmXHU5Zjk5In19.Ukd7trwYMoQmahOAtvNynSA511mseA2ihejoZs7dxt0"; //签发的Token
try {
JWT::$leeway = 60;//当前时间减去60,把时间留点余地
$decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
$arr = (array)$decoded;
print_r($arr);
} catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
echo $e->getMessage();
}catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
echo $e->getMessage();
}catch(\Firebase\JWT\ExpiredException $e) { // token过期
echo $e->getMessage();
}catch(Exception $e) { //其他错误
echo $e->getMessage();
}
//Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
}
}


在src目录下的JWT.php中的方法 decode中,可以看到作者是通过多个 自定义 throw new 抛出异常的

 

 

所以我们可以根据不同的throw new设置多个catch来捕获。

输出的数据:



Array
(
[iss] => http://www.helloweba.net
[aud] => http://www.helloweba.net
[iat] => 1525340317
[nbf] => 1525340317
[exp] => 1525347517
[data] => stdClass Object
(
[userid] => 1
[username] => 李小龙
)

)


五:模拟实战

1:方案:客户端通过用户名密码登录以后,服务端返回给客户端两个token:access_token和refresh_token

access_token:请求接口的token

refresh_token:刷新access_token

举个例子:比如access_token设置2个小时过期,refresh_token设置7天过期,2小时候后,access_token过期,但是refresh_token还在7天以内,那么客户端通过refresh_token来服务端刷新,服务端重新生成一个access_token;如果refresh_token也超过了7天,那么客户端需要重新登录获取access_token和refresh_token。

为了区分两个token,我们在载荷(payload)加一个字段 scopes :作用域。

access_token中设置:scopes:role_access

refresh_token中设置:scopes:role_refresh

有些人是用一个token,要么设置很长时间过期;要么设置几个小时过期,如果过期,用过期的token去换取新的token,这种其实是有问题的,有些人说token有两个时间,一个是过期时间,一个是刷新时间,只要在刷新时间内就可以换取新token。假如别人拿到了你这token,如果也在过期时间之内,不是同样可以刷新token?除非两个token都拿到,相对来说第二种更安全。


直接上代码:



<?php
use \Firebase\JWT\JWT; //导入JWT
class MainController extends Controller
{

public function authorizations()
{
$key = 'ffdsfsd@4_45'; //key
$time = time(); //当前时间

//公用信息
$token = [
'iss' => 'http://www.helloweba.net', //签发者 可选
'iat' => $time, //签发时间
'data' => [ //自定义信息,不要定义敏感信息
'userid' => 1,
]
];

$access_token = $token;
$access_token['scopes'] = 'role_access'; //token标识,请求接口的token
$access_token['exp'] = $time+7200; //access_token过期时间,这里设置2个小时

$refresh_token = $token;
$refresh_token['scopes'] = 'role_refresh'; //token标识,刷新access_token
$refresh_token['exp'] = $time+(86400 * 30); //access_token过期时间,这里设置30天

$jsonList = [
'access_token'=>JWT::encode($access_token,$key),
'refresh_token'=>JWT::encode($refresh_token,$key),
'token_type'=>'bearer' //token_type:表示令牌类型,该值大小写不敏感,这里用bearer
];
Header("HTTP/1.1 201 Created");
echo json_encode($jsonList); //返回给客户端token信息
}
}


看起来输出是这样的:



{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC93d3cuaGVsbG93ZWJhLm5ldCIsImlhdCI6MTUyNTQxNzg5NywiZGF0YSI6eyJ1c2VyaWQiOjF9LCJzY29wZXMiOiJyb2xlX2FjY2VzcyIsImV4cCI6MTUyNTQyNTA5N30.Nxp1yutwt8Fxj5XEzes4j-X4tCBQwE0htEV3Msm2D8s",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC93d3cuaGVsbG93ZWJhLm5ldCIsImlhdCI6MTUyNTQxNzg5NywiZGF0YSI6eyJ1c2VyaWQiOjF9LCJzY29wZXMiOiJyb2xlX3JlZnJlc2giLCJleHAiOjE1MjgwMDk4OTd9.YY8Lid3nk3bnV-ZnAYneKJxGiaD73waqTpC3bHz3wsY",
"token_type": "bearer"
}


http头部响应是这样的:两个token客户端保存,一个用来取接口,一个用来刷新接口。

 

 客户端请求的时候在http头部携带 Authorization: bearer token,注意bearer后面有个空格,我们用PHP模拟一下

 

 

 

 

请求信息是这样的,PHP获取Authorization信息判断。

 

 

 

这个只是一种思路,大家可以按照自己的思路去弄,这种思路服务端不用保存token,但如果涉及到token的注销就必须保存,比如token没过期,但是要注销token,这时候可以上redis。

 

 

 

最后请务必使用HTTPS

 

 

------------------------------------------------------------------------------------------------------------------------------------------

1 安装



composer require firebase/php-jwt


2 用法



se \Firebase\JWT\JWT;
$key = "example_key";
$token = array(
"iss" => "http://example.org",
"aud" => "http://example.com",
"iat" => 1356999524,
"nbf" => 1357000000
);
$jwt = JWT::encode($token, $key);
$decoded = JWT::decode($jwt, $key, array('HS256'));
print_r($decoded);

$decoded_array = (array) $decoded;

JWT::$leeway = 60; // $leeway in seconds
$decoded = JWT::decode($jwt, $key, array('HS256'));


3 补充捕获异常



try {
$arr = $jwt::decode($token, $key, array('HS256'));
} catch (\Exception $e) { // token验证失败
return json(['code' => 0, 'msg' => $e->getMessage()],400)->send();
}catch (ExpiredException $e){ // 过期
return json(['code' => 0, 'msg' => $e->getMessage()],400)->send();

}



    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/26442.html

    分享给朋友:

    “php firebase/php-jwt token验证firebase/php-jwt” 的相关文章

    搬瓦工VPS服务使用指南与优惠码获取技巧

    搬瓦工(BandwagonHost)是一家成立于2004年的网络服务公司,隶属于加拿大IT7。这家公司的崛起与它提供的超低价格VPS服务密不可分,尤其是在中国市场,搬瓦工已经积累了大量的用户和知名度。随着时间的推移,搬瓦工不仅没有止步于低价策略,而是逐渐向中高端VPS市场发展,推出了诸如CN2 GI...

    如何选择RN套餐性价比高的VPS服务

    RN套餐概述 在谈论RackNerd之前,我想先简单介绍一下这家公司。RackNerd成立于2019年,它是一家专注于虚拟主机和VPS服务的商家。作为市场中的新兴参与者,RackNerd凭借其高性价比迅速赢得了不少用户的青睐。在我了解的多家VPS提供商中,RackNerd以其实惠的价格和稳定的性能脱...

    SSH Client Windows 登录指南:轻松配置与高级功能使用

    SSH 客户端在 Windows 中的概述 SSH,也就是安全外壳协议,是一种用来在网络中进行安全数据传输的协议。它确保数据的机密性和完整性,这对于网络管理员和开发者来说是至关重要的。在Windows中,SSH客户端直接关系到我们如何安全地登录到远程计算机。通过SSH,用户可以安全地执行命令、传输文...

    波测评分析及其在医疗与教育领域的重要性

    波测评的定义与重要性 波测评是一种重要的技术手段,专注于评估波动的特性和行为。我发现,这种测评方法在多个行业中都扮演了至关重要的角色,比如医疗、工业和电力等领域。以脑波测评为例,它不仅可以帮助医生了解病人的大脑状态,还能在教育领域评估学习能力。这些应用展示了波测评技术在科学与技术进步中的不可或缺性。...

    全面解析VPS测评:如何选择最佳虚拟专用服务器

    了解VPS(虚拟专用服务器)对许多人来说并不陌生。在我们的网络环境中,VPS作为一种重要的服务器解决方案,广泛应用于网站托管、应用开发、以及各种在线服务的支持。VPS让用户可以在共享环境中获得类似独立服务器的资源,提供了灵活性和更好的性能。与共享主机相比,VPS的显著优势在于更高的资源保障和自定义能...

    RackNerd在纽约的数据中心服务与优势

    RackNerd在纽约的数据中心的服务确实引人关注。从基础服务到多样化的产品,RackNerd为各类客户提供了丰富的选择。我对于他们的虚拟主机和独立服务器十分赞赏。这些服务不仅安全可靠,而且具有灵活的配置选项,满足了各种不同需求的用户。对于初创企业或者需要特别高可用性的业务,选择RackNerd无疑...