FlawOpen

flawopen.com/参考/JWT 与 HttpOnly Cookie

localStorage 中的 JWT 与 HttpOnly Cookie:哪个更安全?

认证指南
简短回答

对许多 Web 应用来说,由服务器管理并通过 HttpOnly Cookie 传递的会话是稳妥的默认起点。JavaScript 无法读取该 Cookie,因此更难直接窃取其中的凭据;但它不会消除 XSS:同源注入脚本仍可能发起已认证请求,并读取页面可访问的数据。

安全上的取舍

存储 / 传递XSS 风险CSRF 行为撤销
localStorage bearer token同源 JavaScript 可读取;XSS 可窃取令牌或以用户身份操作。不会自动附加到跨站请求;XSS 和客户端 CSRF 仍是风险。若不检查撤销状态,自包含 JWT 可能一直有效到过期。
HttpOnly cookieJavaScript 无法读取 Cookie 值;XSS 仍能发起已认证请求。按 Cookie 规则自动发送;SameSite 只是 CSRF 防护的一层。不透明会话可在服务器端失效;JWT Cookie 仍需单独的撤销策略。

推荐架构

区分令牌格式、存储方式和会话状态

JWT 是一种令牌格式;localStorage 和 Cookie 是浏览器中的存储与传递机制。JWT 可以存放在两者任一处。Cookie 中的不透明会话标识符通常指向服务器端会话状态。“JWT 还是 Cookie”并不是对等方案之间的直接比较。

不同选择会改变什么

浏览器不会自动把 localStorage 的值附加到跨站请求中,但同源 XSS 仍能读取 bearer 令牌或通过应用执行操作。Cookie 按浏览器规则自动发送;HttpOnly 只是不让 JavaScript 读取其值,并不能阻止注入脚本利用已登录页面。SameSite=Lax 是一层 CSRF 防护,并非完整保证:安全方法的顶层导航和 same-site 请求仍需考虑。不要通过 GET 修改状态,并根据威胁模型使用适当的 CSRF 防护,例如验证令牌和/或 Origin 检查。

撤销能力取决于服务器状态和令牌验证方式,而非存储位置。删除服务器会话记录即可使其失效。若不检查撤销状态,自包含 JWT 可能一直有效到过期;缩短有效期能缩小窗口,但不能消除它。

实用的默认方案

来源与延伸阅读

另请参阅 跨站请求伪造(CSRF,CWE-352):原理与防御方法 — flawopen.com Next.js Server Actions CSRF:Origin 与安全配置 SameSite=Strict 能取代 CSRF 令牌吗? GET 请求需要 CSRF 令牌吗?