JSON Web Tokens(JWT)知识点查漏补缺
最近在做一个统一的授权登录系统,发现我之前做的一个后台管理系统的 jwt 鉴权是不合理的,重新学习了 jwt 的相关知识点。
之前的做法
在很久之前刚毕业那会我做了一个全栈后台管理系统(之前写过分享:https://blog.crazyming.com/technology-sharing/2007/),它的鉴权功能是这样实现的:
- 前端请求登录接口。
- 后端验证用户名和密码。
- 签发 JWT 给前端,并将 JWT 存储到数据库,相关数据表里主要是 userid 、过期时间和 JWT 字段。
- 前端将 jwt 存在本地 ,在需要鉴权的的接口请求头上加上 JWT 和 userid 参数。
- 后端收到请求头拿到 JWT ,检查 JWT 是否有效,然后根据 接口携带的 userid 信息去数据库查 JWT 是否一致,如果 jwt 有效 且和数据库中对应 userId 的 jwt 一致且未超过过期时间,就放行,否则给 403 状态码。(其实有点多此一举,检查 jwt 有效就可以了)。
- 前端收到 403 状态码后 清除登录态,重定向到登录页。
ps:如果想某个用户的 token 失效,在数据库里删掉对应记录就好了。
问题
上面的做法其实违背了 JWT 的无状态思想,这种做法虽然可行,但是它违背了 JWT 设计的初衷。JWT 被设计为无状态的,也就是说服务器不需要存储任何关于 JWT 的信息。JWT 的有效性和完整性可以通过其自身的签名来验证。在 JWT 中,数据被编码(但不是加密,所以不能存储敏感数据),并且有一个签名部分,这个签名是由服务器使用一个密钥生成的。服务器可以使用这个密钥来验证 JWT 的签名,从而确认它的有效性和完整性。
如果将 JWT 存储在数据库中,并且每次请求都去数据库中查找对应的 JWT,那么这种做法更接近于传统的基于会话的认证方式,而不是无状态的 JWT 认证方式。这种做法的问题是,它会增加数据库的负担,尤其是在高并发的情况下。此外,这种做法也会使得应用的水平扩展变得更加困难,因为需要在多个服务器之间同步 JWT 数据。
但无状态的认证机制,JWT 一旦被签发,就不太好让其失效,这里整理了些 让 JWT 失效的手段:
- 短期有效性:通过设置 JWT 的过期时间为非常短(例如15分钟或1小时),这样即使 JWT 被盗,攻击者也只能在很短的时间内使用,可以限制 JWT 被盗的潜在损害。然后,可以使用刷新令牌,该令牌有更长的有效期(例如24小时,7天,甚至更长),来获取新的 JWT。如果需要让用户的所有令牌立即失效,可以使该用户的刷新令牌失效从而拿不到有效 JWT。
- 黑名单:当需要单个 JWT 在不更改签名秘钥的情况下失效时。但是,要注意这种策略可能会使系统变得状态化,因为需要在服务器上存储黑名单,这可能会增加服务器的复杂性。建议针对刷新令牌来做黑名单 ,性能上来说更好一些,因为刷新令牌的数量通常比JWT要少,所以更适合用于黑名单。
- 更改签名秘钥:这种方法可以使所有的JWT立即失效,但是这意味着所有的用户都会被登出,需要重新登录。因此,这种方法通常只在签名秘钥已经被泄露,或者在进行系统维护时使用。
JWT 的设计使得它们很难从服务器端直接撤销。如果需要频繁地撤销 JWT,那么可能需要考虑使用其他的认证机制,例如基于 session 的认证。
关键知识点:
什么是JWT?
JWT是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息。一个JWT包含了被称为声明(Claims)的信息,这些信息可以被用来识别用户,给出用户的访问权限,以及其他需要在各个服务之间共享的信息。
无状态身份验证
无状态身份验证的一个主要优点是,它不需要在服务器端维护用户的会话状态,这可以大大减轻服务器的负担。在这种方法中,服务器在用户登录时,签发一个包含用户信息和过期时间的JWT。然后,每次用户请求时,服务器都可以验证JWT的签名和过期时间,以验证用户的身份。由于JWT是自包含的,所以它可以方便地在服务之间传递用户的身份信息。
刷新令牌
尽管无状态身份验证有许多优点,但是它也有一些缺点。一旦JWT被签发,服务器就无法在JWT过期之前使其失效。这可能会导致一些安全问题。例如,如果用户的JWT被盗,攻击者可以在JWT过期之前使用它来访问用户的账户。为了解决这个问题,我们可以使用刷新令牌。刷新令牌可以存储在一个安全的HTTP只读cookie中,以防止被JavaScript访问。当JWT过期时,用户的浏览器可以自动使用刷新令牌来获取新的JWT。这样,即使JWT被盗,攻击者也无法获取刷新令牌,因此无法续期JWT。
版权声明:
作者:东明兄
链接:https://blog.crazyming.com/note/3205/
来源:CrazyMing
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论