我的 SPA 应用程序使用以下体系结构(来源) :
这假设我的客户端应用程序知道刷新令牌,因为如果没有用户凭据(例如电子邮件/密码) ,我需要它来请求一个新的访问令牌。
我的问题: 我在客户端应用程序中将刷新令牌存储在哪里?关于这个主题在 SO 上有很多问题/答案,但是关于刷新令牌的答案并不清楚。
访问令牌和刷新令牌不应存储在本地/会话存储中,因为它们不是任何敏感数据的位置。因此,我将把 访问令牌存储在一个 httpOnly
cookie 中(即使存在 CSRF) ,并且无论如何,我需要它来处理对资源服务器的大多数请求。
那刷新令牌呢?我不能把它存储在 cookie 中,因为(1)它会随每个请求一起发送到我的资源服务器,这使得它也容易受到 CSRF 的攻击; (2)它会发送带有相同攻击向量的访问/刷新令牌。
我能想到三种解决办法:
1)将刷新令牌存储在内存中的 JavaScript 变量中,这有两个缺点:
特别是后者的缺点将导致一个糟糕的用户体验。
2)在会话存储中存储访问令牌,并通过 Bearer access_token
授权头将其发送到我的资源服务器。然后我可以使用 httpOnly
cookie 作为刷新令牌。这有一个我能想到的缺点:
3)将两个令牌都保存在 httpOnly
cookie 中,这有上述缺点,即两个令牌暴露在相同的攻击向量下。
也许还有其他的方法或比我提到的缺点(请让我知道) ,但最终一切归结到 客户端的刷新令牌放在哪里?它是 httpOnly
cookie 还是内存中的 JS 变量?如果是前者,那么我应该把我的访问令牌放在哪里?
如果能从熟悉这个话题的人那里得到任何关于如何做到这一点的最佳方法的线索,我会非常高兴。