在处理基于浏览器的应用程序时,关于安全存储 JWT 令牌的主题已经提出了很多问题。共识似乎是应该使用仅限http、安全的cookies。然而,当涉及短期访问令牌和长期刷新令牌时,存储 JWT 令牌似乎存在许多变化。
我已经确定了以下变化:
1。将 JWT 访问令牌和刷新令牌存储在仅限 http 的安全 cookie 中
优点:
缺点:
这里的最佳答案建议添加 CSRF 令牌:https://stackoverflow.com/a/37396572/6735966
2。将 JWT 访问令牌存储在内存中,并在仅限 http 的安全 cookie 中刷新令牌
优点:
缺点:
在这里推荐,但收到的票数比顶帖少很多:https://stackoverflow.com/a/63593954/6735966
3.将刷新令牌存储在内存中,并将 JWT 访问令牌存储在仅 http 的安全 cookie 中
优点:
缺点:
此处的最佳答案中描述了类似的方法:https://stackoverflow.com/a/54378384/6735966
考虑到在内存中存储 JWT 访问令牌和仅在 http 中刷新令牌的优缺点,安全 cookie 对我来说绝对是一个好主意。然而,尽管这个主题有很多问题,但投票最高的答案都没有考虑这种方法。因此我的问题是:为什么不在内存中存储 JWT 访问令牌并在 cookie 中刷新令牌,而是使用其他方法之一?
将 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 模式。
我确实写了一篇博文,更多地讨论了会话存储的目的以及它如何提高安全性: 通过减少 Cookie 来提高 ASP.NET Core 安全性