JWT避坑指南(遇坑无数,持续更新,希望对新手有用)

本文不画图,不秀 code, 只讲一些概念上的东西, 防止大家误入歧途。
当然水平有限,有错误之处,请多指正,勿喷。

1 最重要的,不要考虑在服务器维护 JWT

Session是把用户认证信息放在服务器管理,JWT则是拿到了客户端,如果再在服务器维护JWT,不如直接用Session,若支持非Web客户端,手写个类Web Session的机制来管理客户端也不是难事,加上还有Redis加持。

理解这一点,能少走很多弯路。只要有在服务器维护JWT的念想,就直接干掉吧,比如:

  • 在服务器端维护一个 JWT token 黑名单。

2 鱼与熊掌不可兼得

2.1 Web Session 方案

优点
  • 自动续期
  • 在线用户列表
  • 踢人下线
  • 并发登录控制等
缺点
  • 依赖 Cookie
  • CSRF攻击(有解决方案)
  • 扩展性问题(spring session + redis)
  • 传说中的性能问题

2.2 JWT Session 方案

优点
  • 不依赖 Cookie,支持各种客户端
  • 自包含(自带防篡改的用户身份信息,比如Payload中存一个用户id或uuid)
  • 服务器存取Session的资源得以释放
  • JSON格式通用,支持各种语言
缺点
  • 看Session优点中的几个问题
  • 用户状态变化(删除,禁用,注销等)影响到业务而Token仍然有效时

3 几个应该知道的

  • JWT是防篡改的,不能通过修改他的过期时间(exp) 来实现续期,一量修改,其实是生成了一个新的 Token
  • 每次请求返回一个新的JWT token 虽然能“解决”续签问题,不说性能上的损耗,光这种做法就觉得不是正确的

4 使用 JWT,几个最佳实践

如果能容忍 JWT 的缺点,采用 JWT,以下是几个比较好的实践

使用 accessToken + refreshToken

  • 认证后,返回 accessToken + refreshToken,并保存在本地, Web下推荐 HttpOnly cookie
  • accessToken 使用 JWT 格式
  • refreshToken 使用 UUID, 并维护在服务器端(使用得较少),不用 JWT (原因见第一大点)
  • accessToken 失效时间应该设置较短,比如10分钟
  • refreshToken 失效时间可以长一点,比如 7 天
  • 请求时只用 accessToken
  • accessToken 失效时,用 refreshToken 返回一个新的 accessToken(刷新 token)
  • 刷新 token 时可对 refreshToken 做自动续期,提高用户体验
  • 最好在 accessToken 在失效前主动 refreshToken
  • 避免同时发送多个 refreshToken 请求

JWT 续签问题

  1. 客户端主动续签
    客户端搞个线程定时主动检查Token过期时间,在过期前 (例如过期前1分钟) refresh一下Token

  2. 服务器端每次都续签
    这个前面讲过,只是一种方法,但太不优雅

  3. 服务器端在Token过期前(例如过期前1分钟)续签
    这个其实比较难掌控,假过期前1分内,客户端没有发请求,就续签不了,眼巴巴看着 session 过期,如果设置得过长,那么前面一个Token还会在相当长的时间内有效。而且假如一个 page 有10个请求同时过来,都达到刷新时间,那么会刷10次,最只有最后一次的起作用

所有续签的话,还是推荐客户端主动续签。

用户注销

用户点击注销,删除客户端 token。如果直接关客户端,只有等 accessToken过期

用户修改密码/禁用用户/删除用户

这几种情况在Session环境中可以更新/失效 session来达到安全要求,
但JWT不行,有效期内的accessToken会通过第一道验JWT的关卡,如果没有第二道验 user 的关卡,就直接通过去做业务逻辑了。

5 关于安全方面,几个认识和实践

  • 使用 https保护你的应用
  • sessionid 和 accessToken 泄露,造成的影响是一样,没有哪个更安全 (所以说 accessToken失效时间越短越安全)
  • 不要在payload中不应该存放敏感信息,这部分客户端是可以解密的。
  • secret_key 放在服务器端,不能泄露。

6 JWT 的使用场景

适合的

  • OneTime Token
  • App Token

不适合的

  • 替代 Session 管理
  • 单点登录

6 BFF, 了解下?

  • 不要设计成让所有类型的客户端调用相同的 API Servers
  • 不同的Front 调用不同的Backend For Frontend Server
  • 那么 WebServer用Session不香么

先写这么多,待补充。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用JWT (JSON Web Token) 进行身份验证和授权时,通常会在令牌过期或需要更新时生成新的令牌。以下是一种常见的JWT更新令牌的方法: 1. 客户端在进行身份验证后,服务器生成一个JWT令牌,并将其返回给客户端。 2. 服务器在生成JWT令牌时,通常会设置一个过期时间(expiration time)。 3. 客户端在后续的请求中,将JWT令牌作为授权凭证携带在请求头或请求参数中发送给服务器。 4. 当服务器接收到带有JWT令牌的请求时,首先会验证令牌的签名和有效性。 5. 如果JWT令牌未过期且通过了签名验证,服务器会处理请求。 6. 如果JWT令牌已过期,服务器可以返回一个特定的响应,提示客户端需要更新令牌。 7. 客户端收到服务器返回的“需要更新令牌”的响应后,可以重新进行身份验证,并请求服务器生成新的JWT令牌。 8. 服务器再次生成一个新的JWT令牌,并将其返回给客户端。 9. 客户端在后续的请求中,将新生成的JWT令牌作为授权凭证携带在请求中。 通过这种方式,可以保持用户的登录状态,并在需要时自动更新令牌,而无需用户手动重新登录。更新令牌的频率可以根据具体需求和安全策略进行调整。 需要注意的是,在更新JWT令牌时,建议使用安全的传输方式,如HTTPS,以确保令牌在传输过程中的安全性。 此外,还可以在JWT令牌的有效期内,使用刷新令牌(refresh token)机制来更新令牌。刷新令牌是一个长期有效的令牌,用于获取新的访问令牌。在刷新令牌过期之前,用户可以使用刷新令牌来获取新的JWT令牌,以延长其访问权限。 总结而言,JWT更新令牌的过程是在令牌过期或需要更新时,重新进行身份验证并生成新的JWT令牌,以便维持用户的登录状态。具体的实现方式可以根据实际需求和安全策略来确定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值