背景
前置文章:浏览器: cookie机制完全解析
在考虑token是否应该存储在cookie或localStorage中时,我们需要综合考虑安全性、便利性、两者的能力边界以及设计目的等因素。
安全性:
Cookies的优势:
Set-Cookie: token=abc123; HttpOnly;Secure;SameSite=Strict;Domain=example.com; Path=/
-
HttpOnly:将 HttpOnly 属性设置为 true 可以防止 JavaScript 读取 cookie,从而有效防止 XSS(跨站脚本)攻击读取 token。这一特性使得 cookies 在敏感信息存储上更具安全性。
-
Secure:设置 Secure 属性后,cookie 只会在 HTTPS 连接时发送,从而防止中间人攻击。这确保了即使有人截获请求,token 也不会被明文传输。
-
SameSite:SameSite 属性减少了 CSRF(跨站请求伪造)攻击的风险,通过指示浏览器在同一站点请求时才发送 cookie。
-
Domain 和 Path:这些属性限制了 cookie 的作用范围,例如仅在特定子域或者路径下生效,进一步提高安全性。
localStorage的缺点:
XSS 风险:localStorage 对 JavaScript 代码完全可见,这意味着如果应用存在 XSS 漏洞,攻击者即可轻易获取存储在 localStorage 中的 token。
能力层面
Cookies可以做到更前置更及时的页面访问控制,服务器可以在接收到页面请求时,立即通过读取 cookie 判断用户身份,返回响应的页面(例如重定向到登录页)。
// 示例:后端在接收到请求时可以立即判断
if (!request.cookies.token) {
response.redirect('/login');
}
和cookie相比 localStorage具有一定的滞后性,浏览器必须先加载 HTML 和 JavaScript资源,解析执行后 才能通过在localStorage取到数据后 经过ajax网络请求 发送给服务端判断用户身份,这种方式有滞后性,可能导致临时显示不正确的内容。
管理的便利性
Cookies是由服务端设置的 由浏览器自动管理生命周期的一种方式
服务器可以直接通过 HTTP 响应头设置 cookie,浏览器会自动在后续请求中携带,无需在客户端手动添加。减少了开发和维护负担,且降低了人为错误的风险。
localStorage需要客户端手动管理
使用 localStorage 需要在客户端代码管理 token,你得确保在每个请求中手动添加和删除token,增加了代码复杂度及出错的可能性。
设计目的:
HTTP协议是无状态的 一个用户第二次请求和一个新用户第一次请求 服务端是识别不出来的,cookie是为了让服务端记住客户端而被设计的。
Cookie 设计的初衷就是帮助服务器标识用户的会话状态(如登录状态),因而有很多内建的安全和管理机制,使其特别适合承载 token 等这些用户状态的信息。
localStorage 主要用于存储客户端关心的、较大体积的数据(如用户设置、首选项等),而不是设计来存储需要在每次请求时使用的认证信息。
总结
在大多数需要处理用户身份认证的应用中,将 token 存储在设置了合适属性的 cookie 中,不仅更安全,还更符合 cookie 的设计目的。
通过 HTTP 响应头由服务端设置并自动管理,极大简化了客户端代码,并确保在未经身份验证的情况下阻断对敏感页面的访问。
因此 我认为 在大多数情况下,将 token 存储在 cookies 中更为合理和安全。
补充
然鹅 现实的业务场景往往是复杂多变的 否则也不会有token应该存储在cookie还是localStorage上?
这个问题出现了。
localStorage更具灵活性
: 不同应用有不同的安全需求,有时 localStorage 可以提供更加灵活和精细化的控制。 开发者可以在 JavaScript 中手动管理 localStorage,包括在每次请求时显式设置认证信息。这种 灵活性 对于一些高级用例和性能优化场景可能非常有用。
所以一般推荐使用cookie 但是在合适的场景下使用localStorage完全没问题。