请教各位一个问题, 为什么 session 机制没有被 JWT 所取代?

2017-08-10 17:57:43 +08:00
 baiyi

最近在细读 REST 那篇论文, HTTP 的设计应该就是来自于这里

看到了 无状态 这里, 有一点小疑问: 为什么 session 机制没有被 JWT 所取代?

session 毫无疑问是不符合无状态的, 它使得会话状态(session state)保存在了服务器中. 产生的问题也很清晰: 由于会话状态保存在了服务器, 所以需要多个服务器间同步会话状态

JWT 就是将会话状态存在了客户端(cookie), 服务器端需要的时候自然会解析验证. 也没有多服务器间的同步麻烦.

但是, 现状却是大多网站都是 session 的机制, JWT 只有小部分的 WEB API 使用.

16769 次点击
所在节点    HTTP
99 条回复
Clarencep
2017-08-11 09:14:31 +08:00
个人感觉是 JWT 太长了
mywaiting
2017-08-11 09:29:21 +08:00
楼主目测只是看看文档,没有实际经手一个完整的项目

session 只是一个概念,一个记录 client 状态的实现,这个角度来说,JWT 本身也是一种 session。而 HTTP 都是使用 cookie 来实现了,这点谁都一个卵样(极少数使用 URL 的 id 化来实现,然后无法避免一旦有人无意分享了这个 URL,顺便也把自己的登陆状态分享出去了,比如以前新浪微博的手机版,靠 URL 里面的 gsid 参数来识别登陆的状态)。

JWT 只是签名过的 cookie,一个有实现规范的协议而已,事实上就是一个加密的 cookie,保存信息容量有限,无法解决服务端过期的实现(可以服务端记录 JWT id 和 timestamp 做到,不过这样不是又回到服务器 session 的实现了么?)还有就是楼上的持久化劫持的问题,在需要大量保存用户数据(超过 JWT cookie 容量的时候),一样需要服务器侧的支持,此时又退化为服务器侧的 session 了。而 JWT 所说的只保存用户 id,根本就是伪命题,数据回到服务器,只有 id 你一样要根据 id 去数据库或者缓存查一次用户 user 自己的其他信息如 name,mail,这时候又退化为服务器侧的 session 了,完全失去其分布式的初衷

服务器的 session 就是一个随机字符串 id 的 cookie 放客户端,服务器来保存该 id 对应的数据,的确是用分布式 session id 同步的问题。然而,多数时候,session id 的保存都在单独的 redis 服务器上了,不是淘宝那样的存在,几台 redis 足够你刷到数千万用户了,根本没有什么好担心的

说到底,还是 HTTP 这个协议已经决定了你的实现的方法,session 能折腾的方向实在不多。而大多数网站的实现都是服务器端的 session,此时,你就应该好好想一下,JWT 是不是有天生的缺陷。

再者退一万步来说,身份识别和保持这事情,不使用中心化的识别和认证是及其困难的事情,无论现在的各种签名、各种算法,其背后还是有着中心化的担保和识别的。

道理都是简单如此

以上,希望有用
littleshy
2017-08-11 10:04:03 +08:00
jwt 适合分布式,但我真正需要分布式的网站也就那几家大厂。
还不如用 session。
baiyi
2017-08-11 10:30:58 +08:00
@mywaiting #62

倒也不是没有项目经验, 只是之前想得太少

session 存在的必要也了解, 只不过太过纠结于存储在服务器端还是客户端了.

您的内容对我很有帮助, 感谢!
kiddult
2017-08-11 11:00:50 +08:00
@baiyi JWT 存的用普通的也能搞定,不过感觉你说的是不是 J2EE 里面的 session ?实际用的时候,除非个人小站,不然不会把 session 放本地内存
kiddult
2017-08-11 11:05:36 +08:00
@baiyi session 放服务器还是客户的都没事,各有利弊,服务器端放单独缓存里面,不要放本地内存就行了
baiyi
2017-08-11 11:10:46 +08:00
@kiddult #66

我认为 jwt 比 Session ID 好的一点在于对客户端来说是可见的, 服务器端只是校验

当然, 不好的点也有, 太大了,增加了每次请求的负担
superboss01
2017-08-11 11:59:57 +08:00
问这种问题就没搞清本质了(什么叫 SESSION,请参考该文字本身的意思)

COOKIE 和 JWT 从本质上看都一样的,可进行用户的身份识别和认证,实现 SESSION 会话,不过侧重点不一样
COOKIE 是传统的久产物,只有一个身份字符串
JWT 虽然也是一个字符串,不过自身包含了身份字符串 TOKEN,签名以及签名方式和一些额外的信息
你可以自己实现一套自己的 JWT,比如 base64(jsonencode([{name:'enc',type:'md5'},{token:'xxx'},{sign:''}])),当然了 JWT 有自己的一套标准

共同点:
COOKIE 是浏览器自身进行了存储,在通信时候浏览器将 COOKIE 信息从存储地方取值后附加到了 HTTP 的 HEADER 头部进行了请求(也可以放入查询字符串)

JWT 也是将信息放入 HTTP HEADER 头部(你放入查询字符串也可以)

COOKIE JWT 都有过期时间,都有身份表示字符串

微小不同点:
COOKIE 依赖了浏览器和 COOKIE 自身的存储方式(比如域名相关)
而 JWT 则脱离了这样约束,特别是当下浏览器和 APP 以及分布式的环境下则体现出了优势了
ieiayaobb
2017-08-11 12:01:01 +08:00
其实服务端注销这个需求是 JWT 的痛点,当然你可以把 JWT 当做一个 id_token 存在服务端,但这样做就舍弃了 token 的无状态的优势了
superboss01
2017-08-11 12:07:42 +08:00
@ieiayaobb 前 2 天都帮人做过 JWT 的实现 业务 JWT 是不需要存储在服务器端的

问题就是过期问题 如果用户在登录获取到 JWT 这个字符串后 我没有采用 JWT 自身的过期,因为需要给用户再从新发送新的有效期 JWT 很明显有些麻烦了

而是采用了 REDIS 进行下 JWT 缓存 用户在进行下 API 请求的时候,我就将该 JWT 在 REDIS 里面进行时间的延长
sampeng
2017-08-11 12:09:01 +08:00
每次有人要用 jwt。我就想怼回去。。。
个人感觉 jwt 更多的是在移动应用里面使用。为啥要这么用?
因为我见过的移动端开发都说不能支持 cookie。也就不能支持 session。既然要 url 传 sessionid。那就干脆 jwt 了。。
这个逻辑我也表示很无语。。。
baiyi
2017-08-11 12:36:19 +08:00
@superboss01 #68

我对比的不是 jwt 和 cookie , 而是 session id 和 jwt
baiyi
2017-08-11 12:37:35 +08:00
@ieiayaobb #69

服务器注销可以不需要存储所有的 jwt 内容, 只存储需要注销的 jwt , 根据注销时间判断, 这是我的看法,
orFish
2017-08-11 12:48:43 +08:00
jwt 本质也是 token,只是可以解析后获得部分用户信息等。

jwt 经常也都是要存 redis 等缓存的
jarlyyn
2017-08-11 12:51:23 +08:00
楼主的问题无非是吧 session 数据放在服务器端还是客户端而已。

本质上还是一个东西。
baiyi
2017-08-11 12:58:59 +08:00
@orFish #74

如果说 jwt 能保存所有的关于身份认证的会话状态, 又不会超出太多大小, 是不是就不需要服务器端缓存了
baiyi
2017-08-11 13:00:22 +08:00
@jarlyyn #75

如果说到本质, 那都是 会话状态
newkedison
2017-08-11 14:40:42 +08:00
baiyi
2017-08-11 14:56:31 +08:00
@newkedison #78

作者写的很有水平

jwt 一旦有状态, 那无非是个更为麻烦的 Session ID

而无状态的 jwt 又有好多缺陷, 很苦恼

作者本人似乎也在 V2EX
newkedison
2017-08-11 15:06:51 +08:00
@baiyi #79

我也觉得写的不错,jwt 可能用在 app 上还是有用武之地的吧,在 web 上还是老实用 session 就行了。

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

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

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

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

© 2021 V2EX