要如何用php实现jwt认证,那我们首先就来认识一下什么是jwt。
什么是jwtjwt(json web token)是为了在网络应用环境间传递声明而执行的一种基于json的开放标准。
jwt的声明一般被用来在身份提供者和服务提揭开的近义词是什么供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。
jwt定义了一种用于简洁,自包含的用于通信双方之间以 json 对象的形式安全传递信息的方法。jwt 可以使用 hmac 算法或者是 rsa 的公钥密钥对进行签名。
jwt有两个特点:
自包含(lf-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库
简洁(compact):可以通过url, p描写荷花诗句ost 参数或者在 http header 发送,因为数据量小,传输速度快
jwt组成
jwt由header,payload,signature三个部分
,下面我们用官网的实例先来讲解一个这三个部分的用法。
header部分:
jwt的头部承载两部分信息:
声明类型,这里是jwt
声明加密的算法 通常直接使用 hmac sha256
完整的头部就像下面这样的json:
{
"alg":"hs256",
"typ":"jwt"
}
对应ba64urlencode编码为:
eyjhbgcioijiuzi1niisinr5cci6ikpxvcj9
说明:该字段为json格式。alg字段指定了生成signature的算法,默认值为hs256,typ默认值为jwt
payload部分:
载荷就是存放有效信息的地方。
标准中注册的声明 (建议但不强制使用) :
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
{
"sub":"1234567890",
"name":"johndoe",
"iat":1516239022
}
对应ba64urlencode编码为:
eyjzdwiioiixmjm0nty3odkwiiwibmftzsi6ikpvag4grg9liiwiawf0ijoxnte2mjm5mdiyfq
说明:该字段为json格式,表明用户身份的数据,可以自己自定义字段,很灵活。sub 面向的用户,name 姓名 ,iat 签发时间。例如可自定义示例如下:
{
"iss":"admin",//该jwt的签发者
"iat":1535967430,//签发时间
"exp":1535974630,//过期时间
"nbf":1535967430,//该时间之前不接收处理该token
"sub":"www.admin.com",//面向的用户
"jti":"9f10e796726e332cec401c569969e13e"//该token唯一标识
}
signature部分:
jwt的第三部分是一个签证信息,这个签证信息由三部分组成:
header (ba64后的)
payload (ba64后的)
cret
hmacsha256(
ba64urlencode(header)+"."+
ba64urlencode(payload),
123456
)
对应的签名为:
keh6t3x1z7mm建兰花hkl1t3r9sqdaxxdzb6siemgmr_6zowu
最终得到的jwt的json为(header.payload.signature):
eyjhbgcioijiuzi1niisinr5cci6ikpxvcj9.eyjzdwiioiixmjm0nty3odkwiiwibmftzsi6ikpvag4grg9liiwiawf0ijoxnte2mjm5mdiyfq.keh6t3x1z7mmhkl1t3r9sqdaxxdzb6siemgmr_6zowu
说明:对header和payload进行ba64urlencode编码后进行拼接。通过key(这里是123456)进行hs256算法签名。
jwt的使用流程
初次登录:用户初次登录,输入用户名密码
密码验证:服务器从数据库取出用户名和密码进行验证
生成jwt:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成jwt
返还jwt:服务器的http respon中将jwt返还
带jwt的请求:以后客户端发起请求,http request
header中的authorizatio字段都要有值,为jwt
服务器验证jwt
php如何实现jwt
这里使用的是php 7.0.31,我们新建一个文件jwtauth.php,完整类代码如下:
<?php
/**
*php实现jwt
*/
classjwtauth{
//头部
privatestatic$header=array(
'alg'=>'hs256',//生成signature的算法
'typ'=>'jwt'//类型
);
//使用hmac生成信息摘要时所使用的密钥
privatestatic$key='root123456';
/**
*获取jwttoken
*@paramarray$payloadjwt载荷格式如下非必须
*[
*'iss'=>'jwt_admin',//该jwt的签发者
*'iat'=>time(),//签发时间
*'exp'=>time()+7200,//过期时间
*'nbf'=>time()+60,//该时间之前不接收处理该token
*'sub'=>'www.mano100.cn',//面向的用户
*'jti'=>md5(uniqid('jwt').time())//该token唯一标识
*]
*@returnbool|string
*/
publicstaticfunctiongettoken(array$payload)
{
if(is_array($payload))
{
$ba64header=lf::ba64urlencode(json_encode(lf::$header,json_unescaped_unicode));
$ba64payload=lf::ba64urlencode(json_encode($payload,json_unescaped_unicode));
$token=$ba64header.'.'.$ba64payload.'.'.lf::signature($ba64header.'.'.$ba64payload,lf::$key,lf::$header['alg']);
return$token;
}el{
returnfal;
}
}
/**
*验证token是否有效,默认验证exp,nbf,iat时间
*@paramstring$token需要验证的token
*@returnbool|string
*/
publicstaticfunctionverifytoken(string$token)
{
$tokens=explode('.',$token);
if(count($tokens)!=3)
returnfal;
list($ba64header,$ba64payload,$sign)=$tokens;
//获取jwt算法
$ba64decodeheader=json_decode(lf::ba64urldecode($ba64header),json_object_as_array);
if(empty($ba64decodeheader['alg']))
returnfal;
//签名验证
if(lf::signature($ba64header.'.'.$ba64payload,lf::$key,$ba64decodeheader['alg'])!==$sign)
returnfal;
$payload=json_decode(lf::ba64urldecode($ba64payload),json_object_as_array);
//签发时间大于当前服务器时间验证失败
if(ist($payload['iat'])&&$payload['iat']>time())
returnfal;
//过期时间小宇当前服务器时间验证失败
if(ist($payload['exp'])&&$payload['exp']<time())
returnfal;
//该nbf时间之前不接收处理该token
if(ist($payload['nbf'])&&$payload['nbf']>time())
returnfal;
return$payload;
}
/**
*ba64urlencodehttps://jwt.io/中ba64urlencode编码实现
*@paramstring$input需要编码的字符串
*@returnstring
*/
privatestaticfunctionba64urlencode(string$input)
{
returnstr_replace('=','',strtr(ba64_encode($input),'+/','-_'));
}
/**
*ba64urlencodehttps://jwt.io/中ba64urlencode解码实现
*@paramstring$input需要解码的字符串
*@returnbool|string
*/
privatestaticfunctionba64urldecode(string$input)
{
$remainder=strlen($input)%4;
if($remainder){
$addlen=4-$remainder;
$input.=str_repeat('=',$addlen);
}
returnba64_decode(s荣辱与共trtr($input,'-_','+/'));
}
/**
*hmacsha256签名https://jwt.io/中hmacsha256签名实现
*@paramstring$input为ba64urlencode(header).".".ba64urlencode(payload)
*@paramstring$key
*@paramstring$alg算法方式
*@returnmixed
*/
privatestaticfunctionsignature(string$input,string$key,string$alg='hs256')
{
$alg_config=array(
'hs256'=>'sha256'
);
returnlf::ba64urlencode(hash_hmac($alg_config[$alg],$input,$key,true));
}
}
以上是文章全部内容,有需要学习与经验交流的友人请加入swoole交流群学习与交流的咱们一起学习,有问题一起交流,一起进步!前提是你是学技术的。感谢阅读!
点此加入该群
这里测试一下
//测试和官网是否匹配begin
$payload=array('sub'=>'1234567890','name'=>'johndoe','iat'=>1516239022);
$jwt=newjwt;
$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.co厂房租赁合同m','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
本文发布于:2023-04-07 22:09:40,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/543d2a228e433078065522351e79f454.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:读懂JWT的使用,你就会用PHP如何实现了.doc
本文 PDF 下载地址:读懂JWT的使用,你就会用PHP如何实现了.pdf
留言与评论(共有 0 条评论) |