关于前后端分离中的 Session 和 Token ,请教大家几个问题。

2020-09-01 22:09:39 +08:00
 mitu9527

1.对于会话来说,JWT 真的算 Token 么?虽然名字中带 Token,但是对于会话来说,我觉得 JWT 其实更像是一种“客户端会话”。客户端会话虽然有一些吸引力,但是带来的问题好像比服务端会话更多,怎么还有好多人推荐使用,是我学艺不精,还是他们没搞清楚?

2.服务端会话已经很成熟易用了,在前端也只需要保存一个会话 ID 而已,在传统的开发模式中这个会话 ID 基本上都是保存在 Cookie 中的。如果在前后端分离这种开发模式下,真的用不了 Cookie (比如说部分客户端不支持 Cookie 或者跨域了),那直接基于 HTTP 头部实现一种替代的会话 ID 传输方式,然后再找一个地方存储这个会话 ID,不就可以了么?我看好像也有些人这么做并且管这个叫 Token 。

3.我还见到一些人说“先输入用户名和密码进行登陆,成功后返回一个 Token,然后后续请求都带上这个 Token,定期更换即可”。从功能上讲,这种 Token 感觉十分类似我们做“保持登陆 7 天”时的那种自动登陆 Token,是么?那这种 Token 和会话好像已经没关系了啊!

所以说在前后端分离中不使用 Cookie 的情况下,Session 和 Token 到底该怎么用?

4355 次点击
所在节点    程序员
28 条回复
mitu9527
2020-09-02 10:57:44 +08:00
@dany813 一般都会设置一个过期时间,这个过期时间也保存在客户端,并随每次请求发送给服务端,服务端做验证,判断其是否过期,过期后就告知客户端该 Token 无效,让客户端重新发起登陆请求去重新生成新的 Token 就可以了。
also24
2020-09-02 10:59:09 +08:00
悄悄的丢链接:
https://www.v2ex.com/t/656457

JWT 是一种 token 生成方式。
Session 是代指一整个会话过程的虚拟概念。

二者并不在同一个层级。
mitu9527
2020-09-02 11:04:14 +08:00
@also24 这篇文章我看到了。
siganushka
2020-09-02 11:46:05 +08:00
“会话”只是一个抽象概念,不管是传统的服务端 session,还是 API 里的 JWT,本质都是把两次本不相干的链接关联起来,session 里的 session_id 和 jwt 中的 token 都需要服务端管理和维护,由客户端负责存储,两次链接发送的值一样,即可认为是同一个会话。

像 JWT 一样,服务端的 session 也可以自定义 session_id 和存储逻辑,因此本质上我认为他们是同一个抽象对于不同场景的不同实现,其直接有细微差别,比方说如果你把 session_id 在 cookie 中的 key 改成 token,值为 JWT 的 token 值行不行?然后自己实现存储逻辑,这不和传统的服务端 session 一样么?

之所以你觉得不一样,可能是因为他们的场景有细微的差别,1 是浏览器对于 cookie 的支持相对于 APP (或各种客户端)更好,因此默认不需要客户端手动操作,服务端就能实现整个 session 实现。2 是对于 JWT 的定义中,一旦服务端颁发 token 给客户端,在过期之前服务端无法撤销。

如果让你自己实现一个类似服务端的 session 功能,你想想你该怎么做?想到最后可能就是另一个 JWT !
timothyqiu
2020-09-02 11:52:03 +08:00
按照附言里的定义,大概比较一下:

1. 客户端可以直接修改 Session 里的会话 ID 来冒充其它人;但客户端没法修改 JWT 里的数据,因为它是签了名的。

2. 客户端可以直接修改 Session 的 Cookie 过期时间(甚至不理会),所以服务器必须自行维护会话过期时间;但客户端没法修改 JWT 里的过期时间,因为它是签了名的,所以服务器不用维护会话过期时间。

3. 服务器可以很方便地主动结束 Session,无需额外设施; Token 如果需要服务器主动回收,则必须自行维护黑名单。

不过对于 Token 在第 3 点 Token 所引入的额外设施,Session 是在第 2 点里引入的,而且 Token 只需追踪服务器主动结束的黑名单,Session 必须则必须为所有已登录用户存一份。

但话还是得说回来,不要重新定义概念,按照正常的定义会更好地理解你想研究的问题。Session 就是会话,你称作 Session 的东西是「基于 Cookie 的服务器会话」,你称作 Token 的东西是「基于 Token 的客户端会话」。Cookie 也可以客户端会话,Token 也可以服务器会话。Cookie 和 Token 是一类东西,Session 是另一类东西。
timothyqiu
2020-09-02 12:00:20 +08:00
啊,第一点里如果你的框架签名或者加密了会话 ID,就和 JWT 没啥区别了 🤷‍♂️
mitu9527
2020-09-02 12:09:54 +08:00
@timothyqiu
1.我拿到了 JWT,还改它干啥,直接盗用了;这和会话 ID 被盗取是一样的。再者会话 ID 就算被改了,服务端也不会认。只要会话 ID 生成的方法没问题,想碰撞会话 ID 也是非常难的。
2.那个是 Cookie 的问题吧。再说在服务端会话数据里面加一个过期时间,和在 JWT 中加一个过期时间有什么本质区别么?能在 JWT 中加,那也能在服务端会话中加。
3. 这个是一个本质的区别。

在前后端分离这块,很多人所说的 Token 确实就是客户端会话,那些 Token 的优缺点也都是客户端会话的优缺点。不过在超出这个范畴,那 Token 的含义就不局限于“会话”了。
timothyqiu
2020-09-02 12:39:05 +08:00
@mitu9527 对,所以本质上是想要比较客户端会话和服务器会话。

Token 和 Cookie 都只是数据的载体,优缺点没什么大区别。无论是加密 /签名 Cookie 数据,还是往 Cookie 里额外存过期时间,本质上就像楼上那个哥们说的,完善到最后你会发现往 Cookie 里存的就是另一种形式的 JWT 。

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

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

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

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

© 2021 V2EX