laravel 将加密后的 session 存储在 cookie 中 https://laravel.com/docs/11.x/session#configuration
JWT 将 session 明文存储,并用 hash 签名防篡改
这两种验证策略的应用场景有什么区别?
为什么在刷新有效期上,存储在 cookie 中的 session ,由后端通过中间件在每次请求时都刷新 session 的有效期;而 JWT 通常分为 access_token
与 refresh_token
,并由前端通过携带 refresh_token
的请求获取新的 access_token
1
Jiubia 65 天前
我的简单理解是 cookie 用于自己平台使用
JWT 用于给第三方调用 |
2
Huelse 65 天前
JWT 符合 http 的无状态,可以发到多台服务器一起使用
cookie 更通用但默认只能单台服务器使用,如果需要跨服务器就需要额外的服务来支持 |
3
thinkershare 65 天前 ![]() JWT 适合: 微服务相互通讯,SSO ,OpenAPI 认证,部分 SPA/Mobile 应用(核心是无状态可以减少每次验证授权的开销)
Session: 传统的前后端耦合的 MVC 引用,安全性高并要求实时销毁授权的,授权信息会快速频繁变化,session 生命期非常短。 重要的是理解 JWT 通过 json 格式(公开 RFC 协议格式), 非对称签名和授权验证端点的组合实现了无状态认证和授权,这种方式在高频的服务相互调用时,可以节省每次都执行完整的重新认证&授权流程的性能开销。 |
![]() |
4
chendy 65 天前
不懂 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 的模式,更加朴实无华适用范围更大 |
![]() |
5
GeekGao 65 天前
JWT 更适合于:需要跨域访问控制或者无状态服务间通信的情况,它提供了一个自包含的、易于验证的令牌。
加密 Cookie 更适合于:需要在客户端存储敏感信息或者管理会话的场景,它通过加密来增强数据的安全性。 一句话总结:它们并不总是相互替代的方案。 |
6
gam2046 65 天前
|
![]() |
7
yodhcn OP @chendy 不,laravel 文档里指的是 value 也存储在 cookie 的情况,这样同是无状态,那么这与 jwt 的使用场景有啥不同呢?
|
![]() |
8
zzzzzzggggggg 65 天前
@gam2046 点开这个链接,第一个帖子就是我发的😸
|
![]() |
9
wunonglin 65 天前
月经贴。站里搜一下就行了
|
10
ExplodingFKL 65 天前 ![]() JWT 和 Cookies 区别和优劣
使用 Google 搜索 或者 V2EX 搜索历史帖子 ❌ 发新帖骗 v 友银币 ✔ |
![]() |
11
yodhcn OP @ExplodingFKL #10 你再仔细看看正文,我了解 cookie 、session 、jwt 的区别,但是像 laravel 这种把 session 存 cookie 里的操作不奇怪吗?
|
![]() |
12
mgcnrx11 65 天前
在很久很久以前的互联网上,前后端还是不分离的。浏览器显示的网页,都是通过后端的模版技术动态渲染成 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 用吗?只是没有这个用的习惯而已。 |
![]() |
13
yodhcn OP @mgcnrx11 #12
我理解你的意思了。 token 中的 payload 只用于鉴权,而 session 中的 payload 可以用于鉴权(将“过期时间”视为一种用户状态),还可以存储一些其它的上下文;而为了保持会话,后端需要在用户活跃期间不断刷新“过期时间”。 session 可以存储用户状态,存储在服务端的 session 可以在让同一用户在不同设备上同步状态,并且不用每次请求都携带用户状态相关的全部参数,只需携带 sessionId 。 从这个角度来看,像 laravel 这种存储在客户端的 session 是不是没有多大意义?既不能在多设备上同步状态,又没必要每个请求都携带用户状态的全部参数,只在必要的 api 里提交必要的参数就可以了。除非,是有希望作为请求参数提交,但又不想在客户端被解读的“用户状态”?这种有类似的场景? |
![]() |
14
EmbraceQWQ 65 天前
那如果我把 jwt 的 token 加点特色然后放进 cookie 里面呢?
|
![]() |
15
aragakiyuii 65 天前 via Android ![]() |
16
anonydmer 65 天前 ![]() 没几个人理解楼主的问题。。。
把 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 |
17
whileFalse 65 天前
JWT:分布式验证,无法直接吊销,所以通过短有效期+频繁刷新实现。
Session:集中式验证(一定要链接 redis 等缓存)可吊销,可实时更新 前者当你在第三方或者客户端直接验证的时候使用。如果你不知道自己在干什么,用 session 。 |
![]() |
18
ragnaroks 65 天前
stateless-cookie 是最早的 authentication ,cookie-session 才是后来的,因为那时候服务器性能孱弱带宽贵,只传递一个 session-id 然后去内存里面查明文可比每次都加密解密高效得多。
cookie 这套适合做 authentication ,jwt 适合做 authorization 。 |
![]() |
19
ragnaroks 65 天前 ![]() 楼上都在扯 session 可能是被主题误导了,楼主说的 session 应当是 claim
|
20
weirdo 65 天前
不要局限于框架的方法,去看 http 协议和 jwt 标准相关的东西
|
![]() |
21
ychost 65 天前
其实本质没区别,无非是放 header 的 key 不一样,但是 cookie 有很多安全机制,浏览器可以保障 http_only 前端不能直接获取这个值而 jwt 这个保证不了
|
22
skuuhui 60 天前
其实没啥本质区别,就是一个加密值在通讯中传递。cookies 也是 http 头。只不过 cookies 有更多的限制情况,jwt 更自由,并且也带来更多不安全因素。如果你很多授权是跨域,跨平台,跨应用的,显然更自由的方式让你开发起来更容易,但不代表其他方式不行,你甚至自定义 token 字段。
|