为什么不将 JWT 访问令牌存储在内存中并将刷新令牌存储在 cookie 中?

Jus*_*ken 7 authentication cookies csrf jwt

在处理基于浏览器的应用程序时,关于安全存储 JWT 令牌的主题已经提出了很多问题。共识似乎是应该使用仅限 http 的安全 cookie 。然而,当涉及短期访问令牌和长期刷新令牌时,存储 JWT 令牌似乎存在许多变化。

我已经确定了以下变化:

1. 将 JWT 访问令牌和刷新令牌存储在仅限 http 的安全 cookie 中

优点:

  • 无法从 Javascript 访问访问令牌和刷新令牌

缺点:

  • 引入 CSRF 漏洞,因此还必须添加 CSRF 令牌

这里的最佳答案建议添加 CSRF 令牌:/sf/answers/2617760071/

2. 将 JWT 访问令牌存储在内存中,并在仅限 http 的安全 cookie 中刷新令牌

优点:

  • 无法从 Javascript 访问刷新令牌
  • 通过 Javascript 发送访问令牌,因此访问令牌不易受到 CSRF 的攻击
  • 刷新cookie只能用于获取新的访问令牌。通过正确的 CORS 设置,恶意方无法通过跨站点请求从响应中读取访问令牌。因此,这种方法对于 CSRF 来说似乎是安全的。

缺点:

  • 可以通过Javascript访问访问令牌(但访问令牌很快就会过期)

在这里推荐,但收到的票数比顶帖少很多: /sf/answers/4451576811/

3. 将刷新令牌存储在内存中,并将 JWT 访问令牌存储在仅限 http 的安全 cookie 中

优点:

  • 无法从 Javascript 访问访问令牌
  • 通过 Javascript 发送刷新令牌,因此刷新令牌不易受到 CSRF 的攻击

缺点:

  • 可以从 Javascript 访问寿命较长的刷新令牌
  • 访问令牌容易受到 CSRF 的攻击

此处的最佳答案中描述了类似的方法:/sf/answers/3806486911/

考虑到在内存中存储 JWT 访问令牌和仅在 http 中刷新令牌的优缺点,安全 cookie 对我来说绝对是一个好主意。然而,尽管这个主题有很多问题,但投票最高的答案都没有考虑这种方法。因此我的问题是:为什么不在内存中存储 JWT 访问令牌并在 cookie 中刷新令牌,而是使用其他方法之一?

And*_*ndy 0

将 cookie 存储在内存中是可行的,但一个问题是如果您有同一客户端的多个实例。

另一种方法是像在 ASP.NET core 中那样进行操作,默认情况下 cookie 会加密存储在会话 cookie 中。但是,此 cookie 不能用于访问任何 API,因为无法从 JavaScript 访问它。此外,为了避免 CSRF 问题,您通常会添加常见的防伪令牌/cookie 以防止 CSRF 攻击。

因此,最常见的方法是将 ASP.NET Core 中的令牌存储在会话 cookie 中。但与此同时,这使得 cookie 增长了不少,所以当你感觉 cookie 大小变大时,你就开始考虑将它们存储在内存或数据库/Redis 存储中。

例如,在 .NET 中,已经通过使用 SessionStore 内置了对此的支持。下图试图展示这是如何工作的,其中 SessionKey 存储在 cookie 中,然后令牌存储在内存/后端中。

在此输入图像描述

是的,这就是它在 ASP.NET Core 中的工作原理,我相信您也可以在其他平台中找到类似的方法。

另一种方法是考虑使用似乎越来越流行的BFF 模式。

我确实写了一篇博文,更多地讨论了会话存储的目的以及它如何提高安全性: Improving ASP.NET Core Security By Putting Your Cookies On A Diet