JWT 与“加密 cookie”的应用场景有什么区别?

171 天前
 yodhcn

这两种验证策略的应用场景有什么区别?

为什么在刷新有效期上,存储在 cookie 中的 session ,由后端通过中间件在每次请求时都刷新 session 的有效期;而 JWT 通常分为 access_tokenrefresh_token,并由前端通过携带 refresh_token 的请求获取新的 access_token

2677 次点击
所在节点    程序员
22 条回复
Jiubia
171 天前
我的简单理解是 cookie 用于自己平台使用
JWT 用于给第三方调用
Huelse
171 天前
JWT 符合 http 的无状态,可以发到多台服务器一起使用
cookie 更通用但默认只能单台服务器使用,如果需要跨服务器就需要额外的服务来支持
thinkershare
171 天前
JWT 适合: 微服务相互通讯,SSO ,OpenAPI 认证,部分 SPA/Mobile 应用(核心是无状态可以减少每次验证授权的开销)
Session: 传统的前后端耦合的 MVC 引用,安全性高并要求实时销毁授权的,授权信息会快速频繁变化,session 生命期非常短。
重要的是理解 JWT 通过 json 格式(公开 RFC 协议格式), 非对称签名和授权验证端点的组合实现了无状态认证和授权,这种方式在高频的服务相互调用时,可以节省每次都执行完整的重新认证&授权流程的性能开销。
chendy
171 天前
不懂 laravel ,但是
session 机制其实类似一种 key-value 结构,session 是 value ,key 由服务端生成给到客户端,客户端请求的时候带着 key ,服务端用这个 key 去找到 session
于是主要的点有这么几个:value 存哪里,key 存哪里,key 怎么传递
1. value 存哪里:分服务器端和客户端,服务器端分内存和持久化(进程内进程外),客户端主要就是 jwt
2. key 存哪里:浏览器的话要么很自然的 cookie ,要么 sessionstorage 之类,其他地方各有各的说法
3. key 怎么传,浏览器的话还是要么很自然的 cookie (但是相对的,可能对带来额带宽占用),要么自己塞 header ,其他地方还是各有各的说法

换个角度,常规 key-value 的,key 通常就是一个不容易重复的字符串,而 jwt 属于 key-value 一体,好处是好做无状态,坏处是 key 太大而且无状态


于是:
jwt 机制属于 key 和 value 一体存在客户端,请求的时候自己往 header 里塞的类型(当然放 cookie 里也行但是有点大),因为无状态且有点大,更适合内部服务间通信
而”加密 cookie“应该是最传统的,http 服务自带的 sesion 放内存,session-key 放 cookie 的模式,更加朴实无华适用范围更大
GeekGao
171 天前
JWT 更适合于:需要跨域访问控制或者无状态服务间通信的情况,它提供了一个自包含的、易于验证的令牌。
加密 Cookie 更适合于:需要在客户端存储敏感信息或者管理会话的场景,它通过加密来增强数据的安全性。

一句话总结:它们并不总是相互替代的方案。
gam2046
171 天前
该说不说,每周至少看到一次。

https://www.google.com/search?q=site:v2ex.com/t%20jwt%20cookie
yodhcn
171 天前
@chendy 不,laravel 文档里指的是 value 也存储在 cookie 的情况,这样同是无状态,那么这与 jwt 的使用场景有啥不同呢?
zzzzzzggggggg
171 天前
@gam2046 点开这个链接,第一个帖子就是我发的😸
wunonglin
171 天前
月经贴。站里搜一下就行了
ExplodingFKL
171 天前
JWT 和 Cookies 区别和优劣

使用 Google 搜索 或者 V2EX 搜索历史帖子 ❌
发新帖骗 v 友银币 ✔
yodhcn
171 天前
@ExplodingFKL #10 你再仔细看看正文,我了解 cookie 、session 、jwt 的区别,但是像 laravel 这种把 session 存 cookie 里的操作不奇怪吗?
mgcnrx11
171 天前
在很久很久以前的互联网上,前后端还是不分离的。浏览器显示的网页,都是通过后端的模版技术动态渲染成 HTML ,返回给浏览器的。那时候还没有 Ajax 的流行,浏览器要做的操作,都得一次一次的请求后端,后端返回一个完整的 HTML 页面来显示结果。

在这个背景之下,HTTP 协议又不支持保持会话。那后端怎么知道多个请求之间的联系?例如某个用户先执行操作 A ,然后执行了 B 。所以,需要一种“保持用户状态”的机制,在后端能保存用户的状态使得后端知道用户执行了哪些操作,又能为这些操作保存一些信息。这个就是 Session 会话了。本质上,它是设计出来“保持用户状态”的。

后来,Ajax 使得异步刷新页面,以及后来大前端的流行,各自新的标准和浏览器技术涌现出来。使得我们有更多的方法来做到类似“保持用户状态”的效果。例如,我们可以把用户的状态保存在浏览器端的 Storage 里面。这时候,就会显得后端 Session 来保持用户状态,没有以前那么必要了。当然,也有很多场景会需要在后端保持用户状态。

那么,在不怎么需要后端 Session 来保持用户状态的场景,后端就不需要为用户专门开辟一个区域来存储,它只需要去知道这个请求是否合法的访问就足够了。所以,开始使用了 token 。

所以,session 会在每次访问后,重新刷新 session 的有效期。因为他需要持续保持会话,只要用户一天不离开,会话都需要继续持续下去。某种程度来说,这个有效期时间也可以当成是某个“用户状态”的数据。

另一方面,在使用 token 时,它仅用于判断请求是否合法访问,没有说要用来保持用户状态的。那就很自然的不会去保持用户状态。所以就是一种固定的有效期。不会像会话的场景一样自动延长。也就是只能手动的通过 refresh_token 来延长。

上面说了这么多,都没有提到 cookie 。我理解的是,用不用 cookie 其实都不影响理解 session 和 token 的一些区别。我不能把 token 放在 cookie 吗?我不能把 sessionid 放在 header 用吗?只是没有这个用的习惯而已。
yodhcn
171 天前
@mgcnrx11 #12

我理解你的意思了。

token 中的 payload 只用于鉴权,而 session 中的 payload 可以用于鉴权(将“过期时间”视为一种用户状态),还可以存储一些其它的上下文;而为了保持会话,后端需要在用户活跃期间不断刷新“过期时间”。

session 可以存储用户状态,存储在服务端的 session 可以在让同一用户在不同设备上同步状态,并且不用每次请求都携带用户状态相关的全部参数,只需携带 sessionId 。

从这个角度来看,像 laravel 这种存储在客户端的 session 是不是没有多大意义?既不能在多设备上同步状态,又没必要每个请求都携带用户状态的全部参数,只在必要的 api 里提交必要的参数就可以了。除非,是有希望作为请求参数提交,但又不想在客户端被解读的“用户状态”?这种有类似的场景?
EmbraceQWQ
171 天前
那如果我把 jwt 的 token 加点特色然后放进 cookie 里面呢?
aragakiyuii
171 天前
anonydmer
171 天前
没几个人理解楼主的问题。。。

把 session 加密存在 cookie 中的目的是实现 SNA 架构( shared nothing architecture ),这样服务器端部署的时候可以方便的做多副本部署,因为 session 不存储在每个副本的节点中,也不存在某个统一的集中式存储(例如 redis 或者数据库),不用去处理传统的 session sticky 和 session 复制的问题。 每次服务器接收到一个请求时,是从 cookie 中解密得到 session 值,这样前后两次请求是哪台服务器处理的就不重要了; laravel 我不知道,但是 Rails 在很久以前就这么干了。

之所以要加密是因为两方面的原因,一方面是要防止客户端篡改数据,另一方面是 session 这个设计中是可以存一些敏感数据的。 有人认为加密这个方式可能存在客户端破解的风险,但是实际来看没啥问题(这点 Rails 的文档中有说明过)。
jwt 的设计初衷不同,jwt 中的 payload 对客户端是透明的,所以 jwt 一般不在里面存敏感数据;当然 jwt 也采用了签名验证的机制来防止篡改。

至于刷新时间问题,jwt 因为设计的默认是无状态的机制,一旦签发了就不可撤销,它的生命周期不受服务器控制,所以为了避免泄露后被复用,就让 access token 尽可能短(一般几分钟),而 refresh token 就相对时间长一些,但是它智能用来获取 access token ,不能干别的。 而加密的 session 因为不存在一个服务器端状态来维护它的时间有效性,只好每次使用的时候刷新一下。

@yodhcn
whileFalse
171 天前
JWT:分布式验证,无法直接吊销,所以通过短有效期+频繁刷新实现。
Session:集中式验证(一定要链接 redis 等缓存)可吊销,可实时更新

前者当你在第三方或者客户端直接验证的时候使用。如果你不知道自己在干什么,用 session 。
ragnaroks
171 天前
stateless-cookie 是最早的 authentication ,cookie-session 才是后来的,因为那时候服务器性能孱弱带宽贵,只传递一个 session-id 然后去内存里面查明文可比每次都加密解密高效得多。

cookie 这套适合做 authentication ,jwt 适合做 authorization 。
ragnaroks
171 天前
楼上都在扯 session 可能是被主题误导了,楼主说的 session 应当是 claim
weirdo
171 天前
不要局限于框架的方法,去看 http 协议和 jwt 标准相关的东西

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

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

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

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

© 2021 V2EX