谁能用简短的语言解释 JWT 和 session 的区别?

2018-10-10 14:15:42 +08:00
 chaleaochexist

我目前的理解是.

JWT 在服务器端只需要验证你的 token 是正确的就可以.也就是说数据库里面只需要保存类似这种.

user_id token

然后服务器接到 token 信息,就知道你是谁了.剩下的信息也都在 token 里面装着.不装在服务器端.

要不然我理解不了 JWT 方式和 session 的区别.

8795 次点击
所在节点    程序员
53 条回复
heimeil
2018-10-10 17:11:02 +08:00
@chaleaochexist 不用存 token 的,只用存时间点就行了,对应用户 id,最好存在内存或 redis 里,过了你 token 配置的过期时间的那个窗口清理掉就行了,没必要一直存着每次都验证一次,这样资源相对节省一点。

这样其实也不是太科学把,应该还可以探索更好的方法的。
sobigfish
2018-10-10 17:15:07 +08:00
xiaoxinshiwo
2018-10-10 17:23:21 +08:00
一个无状态,一个有状态
mokeychan
2018-10-10 17:34:22 +08:00
我理解 JWT 是一种规范,本身是一种生成 token 的机制。
ZSeptember
2018-10-10 17:36:57 +08:00
说是两个概念的明显不理解到底是 session。
leafiy
2018-10-10 18:02:18 +08:00
@571726193

1. 客户端 token 存在 localstorage 或者 cookies 随意

2. jwt token 本身包含过期时间和认证信息和用户 ID,服务端验证时需要解密,解密通过就是已登录用户,不通过就是未登录,逻辑非常简单

!永!远!不!要!在服务端存储任何 token,包括 redis,真的!没!有!必!要!
除非解码加密运算影响到你服务器性能了

一个最简单的 express 的例子,客户端通过 headers 或其他各种方式,每次访问时都携带,服务端接收后解一下
secrets 是定好的,不要泄露

let decoded = jwt.verify(token, secrets);
// decoded 失败直接 401 啊

let userId = decoded.id;
let exp = decoded.exp;
// token 过期了
if (exp < now) {
return res.status(401).send({ reason: 'tokenExpired' });
}
// 验证 userId 是不是存在
省略*****

// 生成新的 token 发回去
签发新的 token ****
res.status(200).send({
token: newToken
})

或者用 expressJwt 直接集成到 router 中

expressJwt({ secret: secrets, credentialsRequired: true })
precisi0nux
2018-10-10 18:13:10 +08:00
@crab 这个还是不是 100%靠谱,改密码只是个例子。时间戳没办法保证一改密码就让 token 失效。
WordTian
2018-10-10 18:16:12 +08:00
jwt 信息存客户端,session 信息存服务器
meik2333
2018-10-10 18:18:07 +08:00
对每个用户添加一个额外的参数一起加密解密,服务器端可以修改这个参数来使 token 立即失效。

django 的 jwt 库我记得可以自定义用户的加密解密函数,把加密后的密码一块加入参数就可以保证修改密码 token 立即失效了。
momocraft
2018-10-10 18:18:52 +08:00
session 是目标(请求关联到实体,多次请求关联到相同实体)

如何传输( cookie 或别的 header,甚至 url 或 body ),内容是什么( key 或实体本身)都是实现细节,包括 JWT
tachikomachann
2018-10-10 18:31:03 +08:00
@crab jwt 是有过期时间,但是只依赖 client 的 jwt 校验,无法做到让会话提前失效。
tachikomachann
2018-10-10 18:34:47 +08:00
@precisi0nux 下面有朋友提到了,就是维护一个失效的 jwt 列表,当然这样就要服务端参与了。
rainonline
2018-10-10 18:55:44 +08:00
@571726193
1,JWT 生成 Token 的过程通常发生在用户登录的时候。在生成 Token 后随用户请求返回给用户,并储存在用户浏览器的 cookie 中。
2,在 JWT 的规范里,服务器在校验 Token 的时候是不需要进行任何比对的。而仅仅通过算法就能计算出该 Token 是否有效。
precisi0nux
2018-10-10 21:10:01 +08:00
@tachikomachann 那这不就不是 stateless 了么?
dorentus
2018-10-10 23:07:01 +08:00
rails 的 session 也可以不存服务器啊,实现细节而已。
gsw945
2018-10-10 23:52:28 +08:00
通常所指的 session,是和 cookie 配对使用的,session 是锁(保存在服务器端),cookie 是钥匙( session-id,存放在客户端,一般是浏览器);客户端发送请求时,查找 session 是否存在(有没有带钥匙?携带的钥匙能否打开锁?)。

而 jwt,类似于一个机关锁,服务器端(可能是分布式,多台服务器)不存储内容,但是记录了开启密码锁的方法;客户端发送请求时,jwt 回传到服务器,尝试用记录的方法去解开机关锁,如果能解开,说明是有效的。

如上 v 友所言,jwt 一般是通过设置过期时间来废弃,但是如果想废弃某一条 token,就需要借助存储手段;但是一般并不是存储完整的 jwt,而是记录 jwt 中的关键信息(比如用户 id ),放入黑名单,就算 jwt 解密成功,但是得到的关键信息在黑名单中,也可以拒绝。

而 session/cookie 方式,session 是存在服务器端的,我把锁销毁了,就算你拿着钥匙来了,找不到能开的锁,也是没用的。
(个人理解,仅供参考)
xiaoshenke
2018-10-11 00:45:03 +08:00
首先你要知道什么是 session session 解决了什么问题。简单来说 session 就是会话,http 协议是短链接是没有会话的概念的,就是说 http 协议干的事情就是一个请求过来返回一个结果回去。但现实生活中,比如我和你交流,我其实想记一下你是谁,下次我和你说话我就知道是你了,这也是 session 会话的意思。因此 session 是一个场景一个目标,jwt 是完成这件事的其中一个实现。
cgpiao
2018-10-11 02:42:06 +08:00
你既然数据库里保存 token 了,那 jwt 和 session 还有什么区别。你根本上理解错了 jwt。
wenzhoou
2018-10-11 07:03:36 +08:00
补充一下。cookie 是浏览器的默认行为。如果你开发的不是网页,是 app,或者将来有可能开发 app,而不想搞两套的话,那就选 jwt。
kran
2018-10-11 07:12:11 +08:00
没人规定 session 存服务器。

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

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

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

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

© 2021 V2EX