为什么那么多 web 系统使用 jwt token 来做身份认证

2021-04-29 15:56:52 +08:00
 aboat365

我个人觉得大量的 web 系统在滥用 jwt token 技术。jwt token 签发后可使用私钥来验证其是否过期和篡改,这个技术用来做下载链接、邮箱验证、或短时间内的一次性验证业务是非常好的。但如果用来做 web 系统的身份认证,那简直糟糕透顶。在真正无状态下,很难平衡签发时间和安全之间的矛盾,还有无法续期导致的用户体验问题。当然,可以打补丁,甚至变得有状态,最后解决以上问题。但是,为什么一开始不用 cookie + session 呢?想听听大家的看法。

12359 次点击
所在节点    信息安全
97 条回复
Biluesgakki
2021-04-30 08:54:44 +08:00
讲道理 既然项目都用了 redis 还用 jwt 干啥。。。
sutra
2021-04-30 08:58:00 +08:00
这个问题我觉得应该分成两部分来讨论,一是服务端验证方案,是 JWT 那样的去中心化存储式的,还是类似 Session ID 那样的中心化存储。然而是和前端的通信协议,是 token 还是 cookie 还是 session……,其实和前端的通信协议没多少可以讨论的,不管是 cookie 还是 session 其本质都是一个字符串那样的 token 。
siweipancc
2021-04-30 09:01:43 +08:00
看一下分布式下的客户端 ws 链接列表怎么维护吧
GooGee
2021-04-30 09:14:59 +08:00
(译)别再使用 JWT 作为 Session 系统!问题重重且很危险。

https://learnku.com/articles/22616
CallMeSoul
2021-04-30 09:20:21 +08:00
什么年代了还用 session ?还在写 jsp ? php 和网页混合?前后端分离了解下,多端了解下。
zzzmh
2021-04-30 09:34:16 +08:00
首先篡改是不现实的,除非你有超算+顶级科学家+无穷的时间
其次如果你服务器要接受超级高并发,就会发现 session 也好,redis 也好,炸内存。分布式是能解但成本捉急。
jwt 是一个折中方案,不是完美方案,但解决 99%的情况没问题,剩下的 1%不管也好,redis 黑名单也好,都不会炸内存了
aboat365
2021-04-30 09:36:45 +08:00
@GooGee #44 这是一篇很棒的文章,较为全面的质疑了 jwt 作为会话系统的优点。但我仍然没有明白,为何大家都在使用 jwt 作会话?
aboat365
2021-04-30 09:51:03 +08:00
@LeeReamond @zzzmh #39 #46 超级高并发,高并发,或未来预期的高并发而选择使用无状态会话来减少服务器压力,这是一个值得进一步探讨的问题。如前回答 #37 所述,无状态性能更优(正比或指数或其它),但作为一个高并发架构,应该有具体的数据来支持。所以,能否分享一下达到何种量级后,无状态性能将显著超越有状态,或者说这将是一个制约系统响应时间的瓶颈。如果有这份数据,将很好的指导架构考量,来决定是否值得缺少有状态的优点,而拥抱无状态。
aboat365
2021-04-30 10:04:26 +08:00
@zzzmh 关于篡改,根据上下文理解你的意思应该是破解 jwt,那确实如你所言,难以破解。但本主题并未说 jwt 容易破解,主题中所说篡改指的是修改了 token ,那么服务器用公钥便能分辨出这是改过的 token,从而实现了防篡改。
zoharSoul
2021-04-30 10:20:45 +08:00
@aboat365 #28
> 无状态 jwt 对比有状态的 cookie + session,整体代码量自然是前者少,而且看起来简单,但后者是作为标准具有广泛的实现,实际使用几乎不用写什么代码(开发者甚至不需理解其原理,现成的实现也能工作的很好)。

re:
这个你说反了, 移动端上要是用 cookie + session 这套机制要额外写很多代码, 并且复杂很多.
aboat365
2021-04-30 10:26:42 +08:00
@zoharSoul #50 我未做过移动端开发,不知道移动端使用 session id 会比使用 token 复杂多少?但请你不要骗我。如果是真的,那这是一个考量点。
EIJAM
2021-04-30 10:35:29 +08:00
@zoharSoul 移动端把 sessionid 存在 local storage 里面,会用更多代码么?
a728976009
2021-04-30 10:43:53 +08:00
因为 oauth 和 oidc 几乎已经成为行业的认证标准了,安全有顾虑你可以用 jwe 代替 jwt
CallMeSoul
2021-04-30 10:44:03 +08:00
@aboat365 cookie + session 是以前时代的标准啊,不是现在的标准啊,现在的标准就是 jwt,而且广泛实现啊,不然也不会这么多人用 jwt,你完全可以自己写个加密协议作为 token 的,就是用了 jwt 这么个标准,而且也是广泛认可的,才这么多人用。不管你承不承认,cookie+seesion 是逐渐淘汰了,jsp 你当我没说。
zoharSoul
2021-04-30 10:51:34 +08:00
@EIJAM #52 首先, 移动端就没有 local storage . 其次, 既然你要手动存, 那存 sessionid 和存 token 的成本是一样的,
也就不存在楼主说的 sessionid 不需要手动处理.
zoharSoul
2021-04-30 10:53:04 +08:00
@aboat365 #51 你可以自己试一下啊, 麻烦的点我已经说过了,
两个情况:
1. 你想用 cookie 来保存, 这种情况下非常复杂, 尤其涉及多域名切换, 和 h5 共享登录状态等等.
2. 如果你拿着 sessionid 当 token 存, 那这种情况下, 没有任何优势, 成本是一样的.都是手动处理.
chhpt
2021-04-30 10:55:47 +08:00
JWT 和 Cookie 、Session 不是对立的关系,实际上往往是结合使用的。登录鉴权本质上是客户端需要有一个服务端认可的身份标识,而 Session ID 和 JWT 都是这样的身份标识字符,本质上来说区别不大,Cookie 也只是一种保存身份标识的手段。如果在签发 JWT 时加入身份信息,验证 JWT 后再验证身份信息,就变成了有状态的 JWT,就和 Session 没有区别了。

JWT 本质上是一种加密算法,仅此而已,而使用 JWT 的原因大概只是因为它是一种通用规范,支持较好。
kahlkn
2021-04-30 11:01:47 +08:00
如果 jwt 真的那么好,那么你们会发现 各种开放平台,比如 微信三方登陆,阿里云的各种接口等应该都走 jwt 才对。 然而并没有,他们的 appSecret 也好 accessKeySecret 也好,没有一个走 JWT 的。 他们的量级够大把,他们的开发团队够强把,如果这个机制( JWT 的思路,毕竟大厂,也许会自己造轮子)真的好用,他们应该会用上才对。

看看微信的 三方登陆,拿 appId 和 appSecret 去换 access_token (类 UUID 的字符串,其他参数不管)。然后其他接口比如 获取用户的信息的接口,是需要传入 access_token 的(这不就是类似于 session id 的机制嘛)。

人家大厂还在用类似于 session id 那套,等哪天各种 各类的技术博客啥的(比如 美团技术团队 那个博客,还有一些大佬的博客)都强推 JWT 了,再考虑 JWT 把。
HashV2
2021-04-30 11:02:07 +08:00
我也不想用 领导要求的
a728976009
2021-04-30 11:05:33 +08:00
另外用 session cookie 做单点登录就十分恶心,大型的分布式架构上体验不佳。
认证协议的发展是一个过程,从 session cookie -> saml -> oauth -> oidc,到现在流行的 idaas 服务,每一步发展都是有原因的,你不能倒退着来。
当然这也不是说 session cookie 就无用武之地,session cookie 还有很多使用场景的。
另外 jwt 是分为 jws 和 jwe 的,我们通常指的都是 jws,应该把它看成是一个 encode 方式,jwe 才是 encryption,但这些都不能和认证协议等价。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/774127

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX