授权代码授予:将令牌发送给客户端是否安全?

时间:2021-02-20 04:26:39

标签: firebase oauth-2.0 firebase-authentication openid-connect

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

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

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

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

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

但我在想:这就是 Firebase 的作用,不是吗?据我所知,Firebase 使用授权代码(没有 PKCE),重定向到 Firebase 应用的后端(__auth/handler),然后 它仍然将令牌提供给前端 -结束(id 令牌、访问令牌、刷新令牌)。

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

附注。显然,在 Firebase 的情况下,后端实际上不会使用这些令牌,它依赖于我想象的每个请求中发送的浏览器令牌。不过,在我提到的情况下,后端存储这些令牌,因此理论上我将有 2 组令牌:后端通过代码交换收到的令牌,以及发送到浏览器的令牌(最初它们是相同的,但在第一次刷新后它们是不同的)。后端是否应该完全丢弃令牌并依赖浏览器的令牌?我认为应该如此,因为如果启用了刷新令牌轮换,则在浏览器第一次刷新后,后端将具有无效的刷新令牌。这种情况让我发疯。我的观点是令牌应该保留在后端,但我正在尝试弄清楚 Firebase 方法如何安全。

1 个答案:

答案 0 :(得分:0)

有趣不是吗?涉及到权衡,不同的技术对如何使用令牌做出不同的选择。

简短回答

如果在浏览器中使用访问令牌本身并不是不安全的。通常建议保持令牌的短暂性和机密性,并将它们仅存储在内存中。

是否使用这样的代币也可能取决于数据敏感性和利益相关者的意见。

大图

我们真正希望这两种技术能够以等效的技术方式工作。毕竟,两者通常都需要做同样的工作,即调用 API 来访问数据,然后向用户展示屏幕。

  • 网络用户界面
  • 移动用户界面

在移动用户界面中使用访问令牌是完全标准的,但有些人担心在网络用户界面中这样做。

网络用户界面

如您所描述的,一种选择是将令牌排除在浏览器之外并使用“网络后端”。许多人从安全角度来看更喜欢这种方式,但与纯 SPA 架构相比,它有以下缺点:

  • 您必须通过网络后端对 API 的所有调用进行双跳,这样效率较低
  • 需要运行代码来发布身份验证 cookie 的网络后端可能会导致托管不理想,您无法使用内容交付网络部署网络资源
  • 由于有两种形式的后端凭据,还存在其他复杂性:用于网络的 cookie 和用于移动设备的令牌

2021 年的所有权证明?

希望这些对于公共客户端来说并不遥远——DPoP 令牌可以在 Web UI 和 API 之间发送。这意味着从浏览器窃取的访问令牌无法重放,并将进一步减少对 Web 后端的需求:

浏览器威胁

当然,浏览器安全不仅仅是 cookie 和令牌,而且安全是关于覆盖风险。值得考虑与您有关的威胁以及如何减轻它们 - 这篇博文有一些关于我如何为我的在线代码示例推理的注释: