关于 JWT 到底比 session 强在哪些地方?
发布于 6 年前 作者 mintsweet 8803 次浏览 来自 问答

昨天开始着手用Koa重构Express的时候,在Github上面发现Koa组织里面关于jwtstar数比session更高,加上公司里面Java也是使用的JWT的认证方式,所以就很好奇的去查阅了一番关于它的知识,但是得到的结果并不满意,所谓的优点在我看来并没有比session更加强大,加上公司不大,大家了解不深,所以只能请教一下有深入了解的大神们。

有以下几点疑问

看了一些文章,对JWT本身有一些疑问,希望不吝赐教。

使用更简单

由于JWT本身需要你手动续时,而且续时是一件还挺麻烦的事情,而session是不需要的,那为什么会更简单?

更灵活

这一点的体现在哪里?能同时在不同的server下使用?但是我使用外接专门保存session的服务不也能达到同样的效果吗?

内置过期功能

这一点session是自带的啊,所以好在哪?

实在是好奇应用场景

- 有人说纯API的服务好用?但是也没说清楚好用在哪?
- 有人说它更加的安全,存储在`client`下面真的更加安全吗?
- 有人说它更容易扩展,很好奇什么业务下需要扩展什么东西?

问题略多,还请见谅,因为实在是有太多疑问了,google了一番心中的困惑确实也没有解开很多,望见谅。

37 回复

简单说2点吧

  • jwt一般用于api鉴权,是无状态的,鉴权成功后,token由client持有,每次api请求带上token即可。
  • session是http会话,是有状态的,一般类似于tomcat的ttl是半小时,以前用户登录后下的订单类的都是走session的,现在session也持久化了,用处不大

@i5ting 想知道怎么判断什么情况下改用 jwt 什么情况下还是使用 session,麻烦您啦

资料真的太多了 我现在就用jwt感觉很好用 https://juejin.im/post/5a437441f265da43294e54c3

@hewentaowx 这些东东我是看过了,也明白原理是什么,我就是想不通它到底优秀在哪,为什么别人说它差…

https://scotch.io/bar-talk/why-jwts-suck-as-session-tokens

https://www.zcfy.cc/article/stop-using-jwt-for-sessions-joepie91s-ramblings

@hewentaowx 东西并不是一味的吹它好,我想知道的是它到底哪里好,在用的时候觉得比 session 方便在哪里。

有利有弊:

  1. 以前分布式的session都是通过保证储存位置一致 或者 session共享复制 或者 通过会话保持实现
    • 会话保持的话,如果对应的那台机挂了,这个用户就一直无法获取正常的服务
    • session共享复制的话,效率不会太高,高吞吐效果差
    • 储存位置一致比如nfs或直接使用redis或memcache,和上面有点像,每一次都要去session储存服务中心去取一次或多次,多N次通信交互
  2. 使用jwt的话,避免了上面3个问题

@zy445566 谢谢啦,对应的几点疑问,还希望能够告知

1. 会话如果不保持,服务端对客户端的控制权就降低了,相当于客户端拿到token之后就能为所欲为,这个怎么控制呢?session可以清除,在jwt中是否需要实现这种机制,如果不实现是否会存在我之前的问题?
2. 共享机制是jwt的一大优点
3. 如果使用 jwt 就需要使用频繁的手动续时操作,这个与session频繁的取差别很大吗?还是说,续时操作能有更高级的做法。

@mintsweet 说一点我遇到的吧 做分布式的时候用session难免要做数据持久化吧走数据库查询吧 用jwt至少避免了这个问题。 而且我知道如果在没有完全知晓为什么的时候,大部分人说它好那一定有它好的道理。其实很简单 你对比一下session可以使用的场景jwt是否适用 jwt使用的场景session是否适用 对比一下优劣度不就好了 ,没有绝对好的东西只是相对好就可以了

@hewentaowx 谢谢,说的很中肯,确实不会有完全好的东西,所以我好奇的是使用场景,什么情况下,使用 jwt 比起使用 session 好得多呢?

@mintsweet 第一 客户端拿到token但是解密加密都在服务端如果客户端没有密钥有token也没有什么用,而且后端可以设定密钥不定期更改 第二 jwt的续时问题 你写一个公共方法 在需要登录之后的操作每次调用接口可以用旧token换新token 如果长时间没有调用接口到了token过期之间自然会强制登录 虽然和session频繁取差不多 但是看广度、优劣度选一个就好了

@hewentaowx 明白你的意思啦…万分感谢!

@mintsweet 其实讲道理你的习惯比我好 我当初就没想那么多 看了一些文档觉得场景更适合就用jwt了

@hewentaowx 可能受了点别人的影响吧,嘻嘻…麻烦你了

@mintsweet

  1. 这是两个问题
    • 会话保持不是你想的这样,原理是通过cookie的中session_key值hash到固定的某台机器上,保证这个用户每次访问都会访问到同一台机器,这样session数据就不用共享了,至少我们这边叫这个会话保持,我想你可能理解错了。
    • 很简单全部清除的方式就是换私钥不就好了,你要清除某个人的话,jwt数据里面存用户类型和要过期的时间不就好了,判断该丢弃就丢弃
  2. 我说共享机制是原来session的缺点,没说是jwt优点
  3. jwt解密完数据就在那台机器的内存里面了,不需要去redis读数据,省网络时间。如果是原始的频繁读本地的话,文件是有锁的。

@zy445566 感谢感谢,还有太菜的锅…

jwt最大的优点就是服务端不需要额外存储 当然这也是缺点

我个人使用jwt会把jwt储存在redis,每个用户登录和登出都去redis检查用户的token列表中的jwt是否过期,过期的去掉,收到的token不仅要检查有效性还要去列表检查,不存在也视为无效,用户登出也要请求,服务端把当前token去除,这样实现jwt也有状态。

@HobaiRiku 这不就是一般session的做法么?

就像一楼说的 还是要根据你的业务使用场景来。毕竟jwt里面的数据是明文的。

jwt最初被使用好像是因为session在服务端存储量太大到影响使用

@poorEnMe 是类似,但是session是由浏览器cookie决定的,遵循一些默认的规则,而jwt是应用程序自己控制的,对于分离api模式的开发来说,我不许需要太纠结cookie等这些东西,我觉得是抛弃了cookie这种规则而自己定了轮子,我的理解是这样。

如果完全是由客户端来保存,服务端没法清除的,就算主动清除了,如果有心,客户端也能够备份一个再恢复。

jwt问题是如果涉及到用户权限修改或者登出都不适合,数据时效性差。如果你存状态那就又和session相识了。 感觉小项目不涉及用户权限,单点登录之类的都可以用jwt。相反还是老实用session

以我的经验来看,jwt的优点在于其无状态,服务端对于签发出去的jwt无需保存,解析完就能用。解决了session的从哪读,怎么读的蛋疼问题。 但是同样,它的缺点也是无状态。对于签发出去的jwt,服务端没有很好的办法管理他,不像session只要删了就搞定了

给楼主点个赞,会想敢问,不知道楼主有没有被说服,但我看完上面的讨论是没有被说服的。 jwt不用在服务器存储“session”,这最多算一个特点罢了,不知道怎么就变成了优势… 有谁把session放Redis里面,然后由于应用分布式部署然后单点Redis扛不住?扛不住不是还有集群么,关键是有多少公司能遇到这样的并发量?

@Shasharoman 说实话用了一段时间确实没发现jwt比起session有多大的优势,我现阶段只能理解说jwt在多个服务中还是更方便一些吧。

jwt的优势用session也没问题,jwt的缺陷用session依然可行。比如,token强制失效如果只能用存储session的方式来解决,那声称jwt比session更厉害不就是个笑话了吗?

来自✨ Node.js开源项目精选

@Shasharoman 没错,而且token因为基于算法。所以如果要实现强制失效,最后还得存数据库。真是个笑话。。。也不知道鼓吹jwt优越的人咋想的,完全不考虑实际情况,漏洞那么明显。

来自✨ Node.js开源项目精选

@jinboqiao 没错。权限认证的问题若无法在后端控制,那将会是个大漏洞。。。

来自✨ Node.js开源项目精选

@phper-chen 而且是需要附加一个session才能解决的缺点,从而导致 jwt = jwt + session

来自✨ Node.js开源项目精选

有意思的帖子。目前我也没看到有人说明白为啥用jwt

@vendar 浏览器cookie不跨域,token可以跨域,通过api集合访问多服务的情景下,用基于cookie的seesion是很麻烦的,但是基于token的seesion就可以很方便实现,其实我觉得标题就不太准确,seesion是一种概念,jwt是其中一种实现模式,个人觉得都是看场景的,对于前后端分离和微服务架构来说,使用基于token的认证模式,不需要考虑和配置太多事情(cors跨域资源共享机制、jsonp等等东西),jwt也可以有状态,只不过这样做就和基于cookie 的相同,但不是用cookie机制,而是客户端自身维护的token,主要的区别就在这,对于什么jwt不存在服务端什么的,这都是可以自定义的,根本没有什么哪个比哪个好,也不存在什么漏不漏洞,只是功能如此。

@HobaiRiku 这么实用主义地理解,没毛病

来自✨ Node.js开源项目精选

cookie只适用web客户端, jwt没有限制

如果有100个服务器, 100个服务共享session 那么session的保存就成了单点

回到顶部