本地存储与Cookie

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

547409 次浏览

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

此外,您应该更担心兼容性问题:并非所有浏览器都开始支持新的HTML5 API,因此cookie将是您速度和兼容性的最佳选择。

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

如果它是您的客户端(您的JavaScript),那么请务必切换。您通过发送每个HTTP标头中的所有数据来浪费带宽。

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

无论哪种方式,您都希望将会话cookie保留为cookie。

根据技术差异,也是我的理解:

  1. 除了作为一种保存数据的旧方法之外,Cookie还为您提供了4096字节(实际上是4095)的限制-它是每个cookie。本地存储大到每个域5MB-SO问题也提到了它。

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

使用localStorage,Web应用程序可以在用户的浏览器中本地存储数据。在HTML5之前,应用程序数据必须存储在cookie中,包含在每个服务器请求中。可以在本地存储大量数据,而不会影响网站性能。虽然localStorage更现代,但这两种技术都有一些优点和缺点。

Cookies

优点

  • 遗产支持(它一直存在)
  • 持久数据
  • 失效日期
  • Cookie可以标记为HTTPOnly,这可能会限制XSS在用户访问期间对用户浏览器的攻击(不保证对XSS攻击完全免疫)。

缺点

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

本地存储

优点

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

缺点

  • 以前不支持:IE 8,Firefox 3.5,Safari4,Chrome4,Opera 10.5,iOS2.0,Android 2.0
  • 如果服务器需要存储您有意拥有的客户端信息发送它。

localStorage的用法几乎与会话1相同。它们有非常精确的方法,因此从会话切换到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 similarwindow.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不会如果您从“超文本传输协议”切换到“https”安全协议,则可用cookie仍然可以访问。这对如果您使用安全协议,请注意。

在JWTs的背景下,Stormpath写了一篇相当有用的文章,概述了存储它们的可能方法,以及与每种方法相关的(dis-)优势。

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

我附上了下面文章的一些简短片段,以防他们的文章离线/他们的网站崩溃。

本地存储

问题:

可以通过同一域上的JavaScript访问Web Storage(localStorage/ses sionStorage)。这意味着在您的站点上运行的任何JavaScript都可以访问Web存储,因此可能容易受到跨站点脚本(XSS)攻击。简而言之,XSS是一种漏洞,攻击者可以注入将在您的页面上运行的JavaScript。基本XSS攻击尝试通过表单输入注入JavaScript,攻击者在其中放置警报(“您被黑客入侵”);到表单中,以查看它是否由浏览器运行并且可以被其他用户查看。

预防:

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

如果您使用的脚本中只有一个被泄露怎么办?恶意JavaScript可以嵌入在页面上,而Web Storage是这些类型的XSS攻击可以获取每个人的Web存储访问您的网站,没有他们的知识。这可能是为什么一个许多组织建议不要存储任何有价值或信任的东西Web存储中的任何信息。这包括会话标识符和代币。

作为一种存储机制,Web存储不强制执行任何安全传输过程中的标准。读取Web存储并使用它的人必须尽职调查以确保他们始终通过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还是hahagonnahackyou.com.

预防:

除了HttpOnlySecure之外,现代浏览器还支持#0标志。此标志的目的是防止cookie在跨站点请求中传输,防止多种CSRF攻击。

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

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

执行XHR请求时,$超文本传输协议服务从Cookie(默认为XSRF-TOKEN)并将其设置为HTTP标头(X-XSRF-TOKEN)。由于只有在您的域上运行的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/

本地存储可以存储多达5MB的离线数据,而会话也可以存储多达5MB的数据。但cookie只能以文本格式存储4kb数据。

LOCAl和会话以JSON格式存储数据,因此易于解析。但cookie数据是字符串格式。

另外值得一提的是,当用户在某些版本的Safari中以“私密”模式浏览时,不能使用localStorage

引用自2018年MDN主题#0的WayBack Archive:

说明:从iOS5.1开始,SafariMobile将localStorage数据存储在缓存文件夹中,在操作系统的要求下,偶尔会进行清理,通常是在空间不足的情况下。SafariMobile的私人浏览模式也可以完全阻止写入localStorage

Cookies

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

本地存储:

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

主要区别:

容量:

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

浏览器支持:

  • 本地存储: HTML5
  • Cookies: HTML4, HTML5

存储位置:

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

随请求发送:

  • 本地存储:
  • Cookies:

访问自:

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

到期日期:

  • 本地存储:永不过期,直到JavaScript完成。
  • Cookies:是的,有到期日期。

注意:使用它,适合你。

Cookie:

  • 可以被javascript访问,所以Cookie的数据可以被XSS窃取攻击(跨站脚本攻击)但设置HttpOnly标志Cookie阻止javascript的访问,因此Cookie的数据xss攻击保护。

  • 必须有,所以当通过时,是自动删除,即使您忘记删除CookieCookie由于到期日而自动删除。

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

本地存储:

  • 可以被javascript访问,所以本地存储的数据可以被XSS窃取攻击(跨站脚本攻击)然后,正如我所研究的那样,没有简单的预防本地存储XSS攻击

  • 不容易受到跨站请求伪造的攻击。

  • 没有到期日,所以如果你忘记删除本地存储

    本地存储数据可以永远存在。

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

我建议使用Cookie敏感数据本地存储非敏感数据