关于前后端分离中的 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 到底该怎么用?

4327 次点击
所在节点    程序员
28 条回复
Ptu2sha
2020-09-01 22:23:05 +08:00
多个业务的情况下 Session 是单个业务维护登陆用户信息的
而 token 是多个系统共用的登陆鉴权的
KuroNekoFan
2020-09-01 22:41:23 +08:00
jwt 是去中心化,自包含的,必须理解这两点
Mithril
2020-09-01 22:47:57 +08:00
这个东西主要是分布式或者负载均衡里面用,当你同一个用户的两个请求打到不同服务实例上的时候,这两个实例都需要有能力验证它的合法性。
session 的话你就得保证两个请求都进到同一个服务器里才行。或者你确定你的业务规模用不着做这些东西,那直接用 session 最方便。
wellsc
2020-09-01 22:49:30 +08:00
@Mithril 分布式 session 了解一下
mitu9527
2020-09-01 22:51:38 +08:00
@KuroNekoFan 但是我感觉 JWT 的缺点也挺多的,觉得至少在会话这块用起来不合适。
mitu9527
2020-09-01 22:53:48 +08:00
@Mithril 服务端会话有很多种成熟的方案了,小型、中型和大型架构都有,这个觉得不是问题。
tinycold
2020-09-01 22:55:18 +08:00
其实你说的那些都不是啥问题,JWT 最大的问题是一旦发出去了,在它的失效时间到来之前你永远无法撤销它的认证,要是存 redis 里过滤那就太好笑了。

它最大的好处就是"无状态",正如楼上说的,如果要考虑到复杂的认证 /鉴权系统,JWT 是很有优势的,因为 JWT 的灵活性远远高于 session 。如果只是简单的客户端认证,其实和前后端是否分离关系不大,就直接用自带的 session 认证系统基本就能 hold 住。否则你还得设计 token 分发,刷新,过期处理等等麻烦的事情。

不过,小孩子才做选择,成年人什么都要。你可以用 jwt 来存你的 session id,这样不就完美解决这个问题了!!!(狗头,狗头)
KuroNekoFan
2020-09-01 22:57:01 +08:00
@mitu9527 时代变了,以前可能凭证( credentials )和 会话( session )混在了一起,但现在,可能不这样做了(当然你还是可以这样做),而 jwt 的好处在于,payload 是自定义格式的数据
mitu9527
2020-09-01 23:01:42 +08:00
@tinycold 嗯,JWT 最大的特点是存在客户端,而不是服务器端,所以“无状态”,但也正式因为没有存在服务端,所以服务端没办法主动让其失效,只能等其过期。
timothyqiu
2020-09-01 23:02:43 +08:00
Token 这个词本身不应该狭隘地理解为某个特定领域 /框架中的含义,计算机科学范畴广泛使用 Token 这个术语,本质上只要是「一段对用户含义不透明的数据」都可以叫 Token 。JWT 既然是 JSON Web Token,那它就是 Token 。

「服务端会话还是客户端会话」与「使用 Cookie 还是 Token 」是正交的,Cookie 和 Token 只是信息的载体,信息是 SessionID 还是完整的 Session 数据其实无所谓。JWT 的优势是有签名,可以防止数据被篡改。

前后端分离一般见到的都是用 Authorization 报头传 JWT 。RESTful API 的话客户端会话比较多,因为好实现、方便 HTTP 缓存、方便 Scale 。
mitu9527
2020-09-01 23:14:14 +08:00
@timothyqiu 有点懵了,不过还是要说声感谢!
j2gg0s
2020-09-01 23:20:20 +08:00
在你的描述中,session 是指 cookie 中的 kv,token 是指要 header 里面的 kv,那么 session 的相对优势是不需要请求时手动处理,劣势在于 cookie 使用时不易 cross-domain 和 samesite 之类的限制。

JWT 的优势在于可以存储一些无害的信息,减少调用,同时可以通过校验来避免恶意的 DDOS 击穿系统。绝大部分的操作我理解还是不会直接相信 JWT 中的数据。
xuanbg
2020-09-02 07:26:20 +08:00
@tinycold 复杂的认证 /鉴权系统 JWT 根本做不了。把复杂的授权信息放 payload 就是个笑话,而且,最要命的是做不到授权信息的动态更新。


@mitu9527 JWT 最大的特点也是它的最大缺点。
Mithril
2020-09-02 07:39:08 +08:00
@wellsc 去中心化了解一下
Mithril
2020-09-02 07:52:00 +08:00
@mitu9527 这个就是问题,你可以了解一下这些成熟的服务端会话和 JWT 有什么区别。
本质上 JWT 只是解决了“Server 必须要存储 session 信息”这么个事。
因为 Server 端需要存储 session 信息,所以分布式或者复杂均衡情况下需要通过 session 共享,或者数据库,nginx 配置等等方法要么在多个实例里共享 session,要么保证同一个用户的每次请求都打到一个实例里。
而 JWT 你可以根据需求做到不需要先验知识的验证,从而保证多个实例在验证的时候不需要共享先验知识。Token 这种东西也足够灵活,如果简单的验证不够的话你也可以往里面存个 session id 。
Mutoo
2020-09-02 08:04:30 +08:00
JWT 有很多额外的好处。例如可以用非对称加密鉴权,这种无状态鉴权除了 scaling 的好外以外,还有其它玩法:只要把 public key (注意不是 private key )交给乙方,乙方就可以快速鉴权甲方用户,并且也是无状态的,无无需额外的请求。
renmu123
2020-09-02 08:32:17 +08:00
session 是个概念,而 token 是一个具体实现,cookie 也是
meshell
2020-09-02 09:10:11 +08:00
token 无法主动删除更新用户的凭证.
dany813
2020-09-02 09:23:19 +08:00
老哥们一般是怎么刷新 token 的,定时刷新吗
wellsc
2020-09-02 10:01:46 +08:00
@Mithril jwt token 无法被服务端主动撤销,以及潜在的安全问题,就注定无法替代 session ,个人感觉 jwt 存储 session id,服务端使用分布式 session 才是比较好的解决方案

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

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

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

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

© 2021 V2EX