授权码授予:发送令牌给客户端安全吗?



假设我有一个SPA,其后端位于同一域中。如果我必须连接到外部OAuth提供程序(假设是Google),那么授权代码流(不带PKCE)是更安全的选择。这意味着:

  • SPA向授权服务器请求code
  • 然后,它将code发送到后端
  • 后端与AS交换code(和一个secret)以获得令牌
  • 后端设置一个会话Cookie与SPA保持用户登录

这个流是最安全的,因为SPA永远不会看到单个令牌。它不使用它们。如果我必须使用访问令牌向API发出请求,则SPA将向后端发出请求,后端将使用访问令牌获取资源。后端还负责使用刷新令牌。到目前为止一切顺利。

现在,如果后端在成功交换后(一旦它获得令牌),将令牌发送回浏览器,该怎么办?? 这样,客户端就可以自己访问API的端点。

理论上,如果我没弄错的话,应该避免这种情况。将令牌返回给前端有点违背了授权代码授予的目的,您还不如使用授权代码w/PKCE来直接在前端获得令牌,对吗?使用Code Grant,是后端获得身份验证,而不是SPA。

但我在想:这就是Firebase是的,不是吗?据我所知,Firebase使用授权码(没有PKCE),重定向到Firebase应用程序的后端(__auth/handler),然后它仍然给令牌前端(id令牌,访问令牌,刷新令牌).

我错过了什么吗?或者在授权代码授予结束时将令牌提供给前端是否可以?

p。显然,在Firebase的情况下,后端实际上不会使用这些令牌,它依赖于我认为在每个请求中发送的浏览器令牌。在我提到的情况下,后端存储这些令牌,所以理论上我将有两组令牌:后端通过代码交换接收到的令牌,以及发送到浏览器的令牌(最初它们是相同的,但在第一次刷新后它们就不同了)。后端是否应该完全放弃令牌而依赖于浏览器的令牌?我认为应该是这样,因为如果启用了刷新令牌旋转,则后端在浏览器第一次刷新后会有一个无效的刷新令牌。这种情况快把我逼疯了。我的意见是令牌应该留在后端,但我正在努力弄清楚Firebase方法如何才能安全。

我在这里澄清了我最初的答案,因为我的理解从那时起就发生了变化。

2023更新

如果在浏览器中使用访问令牌,建议让令牌保持短暂的、机密的,并且只将它们存储在内存中。但避免可用性问题的唯一方法可能是将刷新令牌存储在本地存储中。

基于浏览器的应用程序OAuth文档提供了最新的最佳实践。这导致许多人使用后端为前端为应用程序发布最新的samesite=strictcookie。这也通常被利益相关者认为更安全。

有关人们关注的威胁的一些背景,请参阅我的浏览器威胁模型博客文章。这篇文章是我在写博客最后一篇SPA的时候写的,它使用了BFF的方法。

最新更新