在基于 Web 的应用程序中,哪里可以正确、安全地存储 JWT 令牌?

Posted

技术标签:

【中文标题】在基于 Web 的应用程序中,哪里可以正确、安全地存储 JWT 令牌?【英文标题】:Where to store a JWT token properly and safely in a web based application? 【发布时间】:2018-07-20 15:25:15 【问题描述】:

我熟悉 Web 存储 API 和 cookie,但我不知道存储身份验证令牌的最安全方式是什么。我想知道这是否会破坏任何第三方库。

我想要一份详尽的可用方法列表,其中包括每种方法的优缺点以及最重要的最佳方法(如果有的话)。

【问题讨论】:

【参考方案1】:
    JWT 永远不应存储在您的 localStorage 中 事实上,它们甚至不应该存储在您的 cookie 中除非您能够实施非常严格的 CSRF 保护

Checkout this for motivation

作为 id_token 的 JWT 就像您的用户凭据 JWT 作为 access_token 就像你的会话令牌

最安全的选项是内存中。 Checkout this for a deep dive

【讨论】:

问题询问在哪里存储 JWT,但您的答案只回答了不存储 JWT 的位置并提供了一些链接。答案大部分应该是自包含的,因此如果链接有答案,最好将这些信息带入您的答案中。【参考方案2】:

JWT 的存储位置

使用基于令牌的身份验证,您可以选择存储 JWT 的位置。我们强烈建议您将令牌存储在本地存储/会话存储或 cookie 中。

Web 存储(本地存储/会话存储)

通常,JWT 放置在浏览器本地存储中,这适用于大多数用例。

使用用户名和密码登录用户时,响应正文包含access_token JWT。然后你需要在客户端代码中处理这个响应。然后可以将此令牌存储在 localStorage 或 sessionStorage 中。

Click here for an example using sessionStorage

localStoragesessionStorage 都扩展了 Storage。它们之间的唯一区别是数据的持久性:

localStorage - 数据一直存在,直到被明确删除。所做的更改会保存下来,可供所有当前和将来访问该网站的用户使用。

sessionStorage - 所做的更改已保存并可用于当前页面,以及将来在同一窗口中访问该站点。窗口关闭后,存储被删除。

Web 存储的缺点

与 cookie 不同,本地存储被沙盒化到特定域,其数据不能被包括子域在内的任何其他域访问。 可通过同一域中的 javascript 访问 Web 存储,因此您网站上运行的任何 JavaScript 都可以访问 Web 存储,因此容易受到跨站点脚本 (XSS) 攻击。 开发人员必须确保 JWT 始终通过 HTTPS 而不是 HTTP 发送。

使用 Cookies

您还可以使用 cookie 来存储 JWT。设置 cookie 的确切方式取决于您使用的客户端语言。

有不同的选项可以控制 cookie 的生命周期:

Cookie 可以在浏览器关闭后销毁(会话 Cookie)。 实现服务器端检查(通常由正在使用的 Web 框架为您完成),您可以实现过期或滑动窗口过期。 Cookie 可以是持久的(在浏览器关闭后不会被销毁),但会过期。 如果设置了httpOnly 标志,则 JavaScript 和服务器端代码都可以读取 Cookie,或者只有服务器端可以读取。

Cookie 的缺点

cookie 的最大大小仅为 4kb,因此如果您在令牌上附加了许多声明,这可能会出现问题。 Cookie 可能是易受攻击的跨站点请求伪造(CSRF 或 XSRF)攻击。当恶意网站导致用户的 Web 浏览器在用户当前已通过身份验证的受信任站点上执行不需要的操作时,就会发生这种类型的攻击。这是对浏览器如何处理 cookie 的利用。使用 Web 应用程序框架的 CSRF 保护使 cookie 成为存储 JWT 的安全选项。通过检查 HTTP RefererOrigin 标头,也可以部分阻止 CSRF。 如果应用程序需要跨域访问,则可能难以实施。 Cookie 具有其他属性(域/路径),可以对其进行修改,以允许您指定允许将 Cookie 发送到何处。

原文:https://auth0.com/docs/security/store-tokens#how-to-implement

【讨论】:

您好,我喜欢您的回答。还有一个问题,虽然提到这个:“与cookie不同,本地存储被沙盒化到特定域,并且它的数据不能被包括子域在内的任何其他域访问”你能提供一个例子吗?这在实践中意味着什么?

以上是关于在基于 Web 的应用程序中,哪里可以正确、安全地存储 JWT 令牌?的主要内容,如果未能解决你的问题,请参考以下文章

从 Flex 3 安全地访问 .NET Web 服务

正确安全地停止SpringBoot应用服务

在Django中,api键存储在哪里?

安全的基于Web的应用程序的测试分片的最佳实践是什么?

如何在 PHP 中安全地返回文件数据

在哪里可以找到基于 IP 的 SSL Azure Web 应用程序的静态 IP?