的 在JWTs的背景下 强> ,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存储不会强制执行任何安全措施 转让期间的标准。谁读取Web存储并使用它必须 尽职尽责,确保他们始终通过HTTPS发送JWT 而且从不HTTP。
为了防止XSS,常见的响应是转义并编码所有不受信任的数据。但这远不是完整的故事。 2015年,现代网络应用程序使用托管在CDN或外部基础架构上的JavaScript。现代网络应用程序包括用于A / B测试的第三方JavaScript库,漏斗/市场分析和广告。我们使用像Bower这样的包管理器将其他人的代码导入我们的应用程序。
如果您使用的其中一个脚本遭到入侵,该怎么办?恶毒 JavaScript可以嵌入页面,而Web存储则可以 损害。这些类型的XSS攻击可以获得每个人的Web存储 在他们不知情的情况下访问您的网站。这可能就是为什么了 一群组织建议不要存储任何有价值或信任的东西 网络存储中的任何信息。这包括会话标识符和 令牌。
作为存储机制,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。无论如何,cookie都将被发送以请求 无论您是在galaxies.com还是hahagonnahackyou.com。
当与HttpOnly cookie标志一起使用时,Cookie无法通过JavaScript访问,并且不受XSS的影响。您还可以设置安全cookie标记以保证cookie仅通过HTTPS发送。这是过去利用cookie来存储令牌或会话数据的主要原因之一。现代开发人员对使用cookie犹豫不决,因为他们传统上需要将状态存储在服务器上,因此破坏了RESTful最佳实践。如果要在cookie中存储JWT,作为存储机制的Cookie不需要将状态存储在服务器上。这是因为JWT封装了服务器为请求提供服务所需的一切。
但是,cookie容易受到不同类型的攻击: 跨站点请求伪造(CSRF)。 CSRF攻击是一种攻击 恶意网站,电子邮件或博客导致用户的情况 Web浏览器在可信站点上执行不需要的操作 用户当前已通过身份验证。这是如何利用的 浏览器处理cookie。 Cookie只能发送到域中 这是允许的。默认情况下,这是最初的域 设置cookie。无论如何,cookie都将被发送以请求 无论您是在galaxies.com还是hahagonnahackyou.com。
可以使用同步令牌模式来防止CSRF。这个 听起来很复杂,但所有现代Web框架都支持 这个。 例如,AngularJS有一个验证cookie的解决方案 只能通过您的域访问。直接来自AngularJS文档: 执行XHR请求时,$ http服务从a读取令牌 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标头 你的申请。
可以使用同步令牌模式来防止CSRF。这个 听起来很复杂,但所有现代Web框架都支持 这个。
例如,AngularJS有一个验证cookie的解决方案 只能通过您的域访问。直接来自AngularJS文档:
执行XHR请求时,$ http服务从a读取令牌 cookie(默认情况下为XSRF-TOKEN)并将其设置为HTTP标头 (X-XSRF-TOKEN)。由于只有您的域上运行的JavaScript才可以 读取cookie,您的服务器可以放心XHR来自 您的域上运行的JavaScript。您可以进行CSRF保护 无国籍者包括一个 xsrfToken JWT声称:
xsrfToken
{ "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/
那么,本地存储速度很大程度上取决于客户端使用的浏览器以及操作系统。 Mac上的Chrome或Safari可能比PC上的Firefox快得多,特别是对于更新的API。一如既往,测试是你的朋友(我找不到任何基准测试)。
我真的没有看到cookie与本地存储的巨大差异。此外,您应该更担心兼容性问题:并非所有浏览器都开始支持新的HTML5 API,因此Cookie是您速度和兼容性的最佳选择。
值得一提的是 localStorage 用户在某些版本的移动版Safari中以“私人”模式浏览时无法使用。
localStorage
引自MDN( https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage ):
注意:从iOS 5.1开始,Safari Mobile会存储localStorage数据 缓存文件夹,偶尔清理,在 操作系统的要求,通常是空间很短。 Safari Mobile的私有 浏览模式还可以防止完全写入localStorage。
Cookie和本地存储有不同的用途。 Cookies主要用于阅读 的 服务器端 强> ,本地存储只能被读取 的 客户端 强> 。所以问题是,在你的应用程序中,谁需要这些数据 - 客户端还是服务器?
如果它是您的客户端(您的JavaScript),那么无论如何切换。您通过发送每个HTTP标头中的所有数据来浪费带宽。
如果它是您的服务器,本地存储不是那么有用,因为您必须以某种方式转发数据(使用Ajax或隐藏的表单字段或其他内容)。如果服务器只需要每个请求的总数据的一小部分,那么这可能没问题。
的 不管怎样,您都希望将会话cookie保留为cookie。 强>
根据技术差异,以及我的理解:
除了作为一种保存数据的旧方法之外,Cookies还可以为您提供限制 的 4096 强> bytes(实际上是4095) - 每个cookie。本地存储大小如此 的 每个域5MB 强> - 的 所以问题 强> 也提到了它
localStorage 是一个实现 Storage 接口。它存储数据 的 没有到期日 强> ,并得到澄清 的 只要 强> 通过JavaScript,或清除浏览器缓存/本地存储的数据 - 与cookie过期不同。
Storage
本地存储最多可存储5mb的离线数据,而会话最多可存储5mb的数据。但cookie只能以文本格式存储4kb数据。
LOCAl和Session存储数据采用JSON格式,因此易于解析。但cookie数据是字符串格式。