为啥不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌?
Posted
技术标签:
【中文标题】为啥不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌?【英文标题】:Why not store JWT access token in memory and refresh token in cookie?为什么不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌? 【发布时间】:2022-01-15 02:25:43 【问题描述】:在处理基于浏览器的应用程序时,关于安全存储 JWT 令牌的主题已经提出了很多问题。共识似乎是应该使用http-only,secure cookies。但是,当涉及短期访问令牌和长期刷新令牌时,存储 JWT 令牌似乎存在许多变化。
我发现了以下变体:
1.将 JWT 访问令牌和刷新令牌存储在仅限 http 的安全 cookie 中
优点:
无法从 javascript 访问访问令牌和刷新令牌缺点:
引入了 CSRF 漏洞,因此还必须添加 CSRF 令牌这里的最佳答案建议添加 CSRF 令牌:https://***.com/a/37396572/6735966
2。将 JWT 访问令牌存储在内存中,并在 http-only 安全 cookie 中刷新令牌
优点:
无法从 Javascript 访问刷新令牌 通过 Javascript 发送访问令牌,因此访问令牌不会受到 CSRF 的攻击 刷新 cookie 只能用于获取新的访问令牌。使用正确的 CORS 设置,恶意方无法通过跨站点请求从响应中读取访问令牌。因此,这种方法似乎不受 CSRF 影响。缺点:
可以通过Javascript访问访问令牌(但是访问令牌很快就会过期)在这里推荐,但获得的票数比顶部帖子少得多:https://***.com/a/63593954/6735966
3.将刷新令牌存储在内存中,将 JWT 访问令牌存储在仅 http 的安全 cookie 中
优点:
无法从 Javascript 访问访问令牌 通过 Javascript 发送刷新令牌,因此刷新令牌不会受到 CSRF 的攻击缺点:
可以从 Javascript 访问寿命更长的刷新令牌 访问令牌易受 CSRF 攻击这里的最佳答案中描述了类似的方法:https://***.com/a/54378384/6735966
考虑到在内存中存储 JWT 访问令牌和在 http-only 中刷新令牌的利弊,安全 cookie 对我来说绝对是个好主意。然而,尽管关于这个话题有很多问题,但投票最多的答案中没有一个甚至考虑过这种方法。因此我的问题是:为什么不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌,而是使用其他方法之一?
【问题讨论】:
【参考方案1】:将 cookie 存储在内存中是可行的,但一个问题是,如果您有同一个客户端的多个实例。
另一种方法是像在 ASP.NET 核心中那样进行操作,默认情况下,cookie 以加密方式存储在会话 cookie 中。但是,此 cookie 不能用于访问任何 API,因为它无法从 JavaScript 访问。此外,为避免 CSRF 问题,您通常会添加通用防伪令牌/cookie 以防止 CSRF 攻击。
所以,将令牌存储在 ASP.NET Core 中的大多数方法是在会话 cookie 中。但与此同时,这会使 cookie 增长不少,所以当你觉得 cookie 变大时,你就开始考虑将它们存储在内存中或数据库/Redis 存储中。
例如,在 .NET 中,已经通过使用 SessionStore 内置了对此的支持。下图试图展示它是如何工作的,其中 SessionKey 存储在 cookie 中,然后令牌存储在内存/后端中。
是的,这就是它在 ASP.NET Core 中的工作方式,我相信您也可以在其他平台上找到类似的方法。
另一种方法是使用似乎越来越流行的BFF pattern。
【讨论】:
您介意解释一下为什么拥有相同客户端的多个实例是个问题吗? 如果您有多个实例,那么如何在不同服务之间共享令牌? (除非您在负载均衡器中使用粘性会话)。通过服务,您更愿意让它们无国籍。还有一个问题是确保加密的 cookie 在不同的服务实例中工作,对于一些需要额外注意和配置的框架。 对不起,我还是不明白。我假设对于多个客户端实例,您的意思是例如两个对同一个 REST api 进行身份验证的单页应用程序 (SPA)。 JWT 访问令牌存储在浏览器内存中,刷新令牌存储在 cookie 中。既然 REST api 是无状态的,为什么服务需要共享令牌? 如果您使用的是经典后端站点还是 SPA,您的问题有点不清楚,我假设是前者。 SPA 应用程序的问题是安全性以及如何管理令牌。一种方法是使用 BFF 模式来避免处理在浏览器中存储和保护令牌的复杂性。 我认为后端处理的越多,安全性就越好。以上是关于为啥不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌?的主要内容,如果未能解决你的问题,请参考以下文章