认识JWT

本文详细介绍了JWT(JSON Web Token)的概念、组成及工作原理,并探讨了其在实际应用中的优势、使用流程、刷新策略、黑名单管理和并发问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用 jwt 也有一段时间了,感觉还是蛮方便的。写一篇文章总结一下。

JWT 是什么

JWT(JSON Web Token)是一个字符串,我们在发起网络请求时,将其放在header或者url中,这样可以保证传递的数据被篡改时能被我们发现,保证安全性。基于token的身份验证可以替代传统的cookie+session身份验证方法。注意:只能防止被修改,不能防止被解码。也就是说不能在 jwt 中存放重要数据。

JWT组成

  • JWT 由3部分组成,用点号连接。

    header.payload.signature

  • header:两个字段都是必须的,alg字段指定了生成signature的算法,默认值为 HS256,可以自己指定其他的加密算法。经过base64encode就可以得到 header。

{
"typ":"JWT",
"alg":"HS256"
}
  • playload :官方说法,三个部分组成(Reserved claims,Public claims,Private claims)。是表明用户身份的数据,可以自己自定义字段,很灵活。经过json_encodebase64_encode就可得到payload。
 $token   = [
            #非必须。issuer 请求实体,可以是发起请求的用户的信息,也可是jwt的签发者。
            "iss"       => "http://example.org",
            #非必须。issued at。 token创建时间,unix时间戳格式
            "iat"       => $_SERVER['REQUEST_TIME'],
            #非必须。expire 指定token的生命周期。unix时间戳格式
            "exp"       => $_SERVER['REQUEST_TIME'] + 7200,
            #非必须。接收该JWT的一方。
            "aud"       => "http://example.com",
            #非必须。该JWT所面向的用户
            "sub"       => "jrocket@example.com",
            # 非必须。not before。如果当前时间在nbf里的时间之前,则Token不被接受;一般都会留一些余地,比如几分钟。
            "nbf"       => 1357000000,
            # 非必须。JWT ID。针对当前token的唯一标识
            "jti"       => '222we',
            # 自定义字段
            "GivenName" => "Jonny",
            # 自定义字段
            "name"   => "Rocket",
            # 自定义字段
            "Email"     => "jrocket@example.com",

        ];
  • signature:加上设置好的迷药秘钥,将 header和 payload使用 header 中指定的加密算法加密。
    连起来就是 JWT 了

原理

最后一步签名的过程,实际上是对头部以及载荷内容进行签名。一般而言,加密算法对于不同的输入产生的输出总是不一样的。
所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的。

基本用法

1. 优势

Session方式存储用户id的最大弊病在于要占用大量服务器内存,对于较大型应用而言可能还要保存许多的状态。一般而言,大型应用还需要借助一些KV数据库和一系列缓存机制来实现Session的存储。
而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。

2.使用流程

这里写图片描述

  • 初次登录:用户初次登录,输入用户名密码
  • 密码验证:服务器从数据库取出用户名和密码进行验证
  • 生成JWT:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成JWT
  • 返还JWT:服务器的HTTP RESPONSE中将JWT返还
  • 带JWT的请求:以后客户端发起请求,HTTP REQUEST HEADER中的Authorizatio字段都要有值,为JWT

3.刷新策略

JWT 有一个过期时间和一个刷新时间。
在过期时间内,可以正常使用。如果超过了过期时间,就需要重新登录。


  • 比较好的做法应该是:

活跃的用户应该在无感知的情况下在JWT失效后获取到新的JWT,携带这个新的JWT进行访问,而长时间不活跃的用户应该在jwt失效后需要进行重新的登录认证。
使用旧的JWT可以获取到新的JWT,新的JWT应该在header中携带,传递给客户端。

4.blacklist

这里好像有一个漏洞,如果刷新JWT,旧的JWT还在有效期内,是不是两个JWT都可以验证通过呢?

其实不会, 刷新之后,旧的JWT会放入blacklist,其实就是放入缓存。如果使用黑名单中的JWT访问,验证失败。

5.并发问题

如果当前 token_1 过期,先发起 a 请求,之后马上发起 b 请求。a 请求到服务器,服务器判断过期,刷新 token_1,之后返回 token_2 给 a 请求响应。这时候迟一点的 b 请求用的还是 token_1 ,服务器已经将此 token_1 加入黑名单,所以 b 请求无效。

JWT已经想到这种情况,我们只需要设置一个黑名单宽限时间 blacklist_grace_period 即可。这个时间应该设置的比较短,在几秒钟都是可以的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值