浏览器中存储访问令牌的最佳实践( 二 )


一些解决方案跨选项卡共享数据,而其他解决方案仅限于当前选项卡 。但是,本指南中介绍的大多数方法都针对每个源存储数据 。因此,对于任何相关讨论来说,理解一些概念很有帮助:origin和site 。
某个(Web)资源的origin是其URL的scheme、hostname和port 。例如,https://example.com/number/one和https://example.com:80/path/two具有相同的origin,因为它们共享scheme(https)、hostname(example.com)和端口(默认端口) 。它们的origin为https://example.com,与https://example.com:8443或https://this.example.com不同,因为它们在端口和主机名上有所不同 。
相比之下,一个site比资源的origin要大 。一个站点是为一组资源提供服务的Web应用程序的通用名称 。简单地说,一个站点是scheme和domain name,如https://example.com 。虽然https://example.com和https://this.example.com:8443有不同的origin(不同的主机名和端口),但它们是相同的站点,因为它们托管在同一个域名(example.com)上并使用相同的scheme(https) 。(从技术上讲,这个定义还有细微差别,但这个简化的说法有助于解释这个概念) 。
本地存储本地存储是通过Web存储API中的全局localStorage对象以JavaScript访问的 。本地存储中的数据在浏览器选项卡和会话之间可用,也就是说它不会过期或在浏览器关闭时被删除 。因此,通过localStorage存储的数据可以在应用程序的所有选项卡中访问 。因此,在本地存储中存储令牌非常诱人 。
// Storing the access tokenlocalStorage.setItem("token", accessToken);// Loading the access tokenlet accessToken = localStorage.getItem("token");每当应用程序调用API时,它都会从存储中获取令牌并手动添加到请求中 。但是,由于本地存储可以通过JavaScript访问,这意味着该解决方案也容易受到跨站脚本(XSS)攻击 。
如果您在本地存储中使用access token,并且攻击者设法在您的应用程序中运行外部JavaScript代码,那么攻击者可以窃取任何令牌并直接调用API 。此外,XSS还允许攻击者操作应用程序中的本地存储数据 , 这意味着攻击者可以更改令牌 。
请注意 , 本地存储中的数据会永久存储 , 这意味着存储在其中的任何令牌会驻留在用户的设备(笔记本电脑、电脑、手机或其他设备)的文件系统上 , 即使浏览器关闭后也可以被其他应用程序访问 。因此,在使用localStorage时,请考虑终端安全性 。考虑并防止浏览器之外的攻击向量,如恶意软件、被盗设备或磁盘 。
根据上述讨论,请遵循以下建议:

  • 不要在本地存储中存储敏感数据,如令牌 。
  • 不要信任本地存储中的数据(尤其是用于认证和授权的数据) 。
会话存储会话存储是Web存储API提供的另一种存储机制 。与本地存储不同,使用sessionStorage对象存储的数据在选项卡或浏览器关闭时会被清除 。此外,session存储中的数据在其他选项卡中不可访问 。只有当前选项卡和origin中的JavaScript代码可以使用相同的会话存储进行读取和写入 。
// Storing the access tokensessionStorage.setItem("token", accessToken);// Loading the access tokenlet accessToken = sessionStorage.getItem("token");与本地存储相比,会话存储可以被认为更安全,因为浏览器会在窗口关闭时自动删除任何令牌 。此外,由于会话存储不在选项卡之间共享,攻击者无法从另一个选项卡(或窗口)读取令牌 , 这减少了XSS攻击的影响 。
在实践中 , 使用sessionStorage存储令牌的主要安全问题是XSS 。如果您的应用程序容易受到XSS攻击,攻击者可以从存储中提取令牌并在API调用中重放它 。因此,会话存储不适合存储敏感数据,如令牌 。
IndexedDBIndexedDB是索引数据库API的缩写 。它是一个用于在浏览器中异步存储大量数据的API 。但是,在存储令牌时,这个浏览器API提供的功能和容量通常不是必需的 。由于应用程序在每次API调用中都发送令牌 , 最好是使令牌的大小最小化 。
与迄今为止讨论的其他客户端存储机制一样 , 使用索引数据库API存储的数据访问受到同源策略的限制 。只有相同来源的资源和服务工作者才能访问数据 。从安全角度来看,IndexedDB与本地存储相当:
  • 令牌可能会通过文件系统泄露 。
  • 令牌可能会通过XSS攻击泄露 。
因此,不要在IndexedDB中存储访问令牌或其他敏感数据 。IndexedDB更适合用于应用程序脱机工作所需的数据,如图像 。


推荐阅读