SPA 中的令牌存储和刷新选项
Posted
技术标签:
【中文标题】SPA 中的令牌存储和刷新选项【英文标题】:Options for token storage and refresh in SPAs 【发布时间】:2020-05-08 01:27:03 【问题描述】:我一直在阅读 Aaron Parecki 的基于浏览器的应用程序草案(意思是使用 React 或 Angular 开发的 SPA)认证最佳实践与 OAuth 2 以及 OWASP 安全指南,这让我非常困惑:
-
RFC 草案提到了轮换刷新令牌。现在我将如何在遵守 REST 的无状态约束的同时做到这一点?我是否在 cookie 和刷新令牌中包含一些随机字符串的摘要并检查它们是否相等?
在浏览器中存储刷新令牌的正确方法(或者更确切地说,一些更安全的方法)是什么?我检查了 okta 的 JS auth 库,它默认使用
localStorage
,这是 OWASP 指南建议的。它有某种额外的保护吗?我是否应该在其中添加一些额外的摘要并将其放入 cookie 中并匹配它们?
OWASP 建议会话 ID 对客户端应该是完全不透明的,但是如果我们使用 JWT,是不是违反了这个原则?这是否意味着我应该始终使用对称密码加密我的 JWT?
一些参考资料:
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps-04#section-4 https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTML5_Security_Cheat_Sheet.md https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/JSON_Web_Token_Cheat_Sheet_for_Java.md https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Session_Management_Cheat_Sheet.md【问题讨论】:
【参考方案1】:传统水疗流程
在传统的 SPA 流程中,使用 iframes to silently renew tokens 是标准的。
同时访问令牌最好只存储在内存中,并且应该是短暂的。在传输过程中仍然存在捕获令牌的威胁,其中一些在 this post of mine 中进行了探讨。
2021 年更新
与 SPA 令牌刷新相关的浏览器有两个重大变化:
浏览器积极丢弃第三方 cookie,这意味着传统的 SPA 令牌刷新不再可靠地工作(例如在 Safari 浏览器中)
浏览器 cookie 的安全性通过 SameSite=strict
cookie 变得更加强大,并且对 XSS threats (video) 的担忧有所增加
前端换后端
因此,现在建议将刷新令牌存储在仅 HTTP 加密的 SameSite=strict
cookie 中。这最好以 API 驱动的方式完成,以避免影响 Web 架构。请参阅blog post,了解一些最新的最佳实践和资源链接,包括 React 代码示例。
【讨论】:
非常感谢!我以前听说过这个解决方案,但我认为我没有提到的是我主要考虑了同源部署。我是否正确,隐藏的 iframe 技巧依赖于安全的、仅限 http 的 cookie 才能工作?但是,如果我们谈论的是同域部署,那不是没有必要吗? IETF 草案提到,在这种情况下 cookie 会更安全,但是为了更容易的潜在迁移,使用更传统的令牌实现所有内容可能是有意义的。在这种情况下,您认为最好的做法是什么? 另外,我对这个问题更感兴趣的是来自一个同时管理前端和后端的全栈开发人员。我只是使用 okta 的库作为我希望在其中找到良好实践的示例。 我的偏好是 SPA 本身是无 cookie 的(它的后端不发出 cookie - 即使浏览器可能使用来自授权服务器的 cookie)。我认为基于令牌的 SPA 拥有最好的 future hosting and extensibility options。在早期,您可以将两者一起托管在同一个域上,例如 mycompany.com/spa 和 mycompany.com/api。您仍然可以以全栈开发人员的方式执行此操作,同时保持关注点分开。 话虽如此,实现基于令牌的架构和引入授权服务器存在成本和学习曲线。基于相同站点 cookie 的解决方案将是安全的,并且可能成本更低 - 因此更容易实现。不过,我仍然会在逻辑上将 API 和 SPA 分开。以上是关于SPA 中的令牌存储和刷新选项的主要内容,如果未能解决你的问题,请参考以下文章
带有存储在 cookie 中的刷新令牌的 SPA - 如何使用 IdentityServer4 进行配置?
带有 JWT 的 AngularJS 或 SPA - 到期和刷新