第三方 API 访问的 OAuth 流程

Mat*_*son 10 authentication oauth oauth-2.0 google-oauth google-sheets-api

网络上有很多有关 OAuth 2、其不同类型的流程以及在何处/如何使用它们的信息。我发现这些资源中的大多数都讨论了对应用程序的用户进行身份验证,但我很难理解在使用第三方 API 时(即,当我们自己的 API 是用户与其用户之间的“中间人”时)最好/正确的方法是什么。第三方 API 中的数据)。

\n\n

在示例场景和一些图表的帮助下,我将非常感谢您就如何正确实现与第三方 API 的集成以及每种方法的优缺点提供建议/意见。

\n\n

初始点

\n\n

首先,假设我们有一个 Web 应用程序,其结构如下:

\n\n
    \n
  • 前端 - SPA (Angular),由 AWS S3 + Cloudfront 托管
  • \n
  • 后端 - 节点,使用 AWS API Gateway 作为无状态 AWS lambda 函数运行
  • \n
  • Auth0 用于处理身份验证/登录等。前端使用隐式 OAuth2 流来获取 access_tokens,这些令牌存储在本地存储中,并作为标头包含在对后端的所有请求中。
  • \n
  • 也可能是本机移动应用程序,使用相同的后端 API。
  • \n
\n\n

目标

\n\n

现在假设我们希望添加与 Google Sheets 的集成。新功能将允许用户使用自己的 Google 表格(即存储在自己的 Google 帐户中)作为数据源,应用程序可以对该表格进行读写访问。将来可能会有其他集成,因此我假设其他 API 也需要类似的过程。

\n\n

问题陈述

\n\n

除了现有的 OAuth 流程(允许用户登录“MyApp”前端并与“MyApp API”通信)之外,还需要一个额外的 OAuth 流程,以便用户将 MyApp 连接到第三方Google Sheets API

\n\n

该文档有两个快速入门示例,但似乎都不太符合我的需求:\n浏览器 - https://developers.google.com/sheets/api/quickstart/js \nNode.js(控制台应用程序) - https://developers .google.com/sheets/api/quickstart/nodejs

\n\n

来自第三方 (Google) API 的数据是潜在的几个集成点之一,因此直观上来说,与 Google Sheets API 的所有通信都应该发生在MyApp API,而不是在前端/客户端上,这似乎更符合逻辑(也更安全)。边。它们MyApp API会获取数据,以某种方式处理/操作/格式化数据,然后将其呈现在前端或移动应用程序中显示。

\n\n

我们需要访问每个用户自己的数据,因此该Client Credentials流程不合适。我专注于ImplicitAuthorization Grant工作流程。

\n\n

重要提示:棘手之处似乎在于它MyApp API是无状态的,因此没有长期会话来存储令牌。在此基础上,令牌似乎需要存储在前端(例如本地存储/cookie 等)或后端数据库中。

\n\n

以下是我对两种可能方法的解释。我很感激想法/更正。

\n\n

选项 1:隐式流程 - 令牌存储在 FE 中,传递给 BE,然后 BE 向 Google 发出请求

\n\n

选项1

\n\n

优点:

\n\n
    \n
  • 允许访问用户自己的数据
  • \n
  • 流程更简单,access_token立即检索,无需code步骤
  • \n
  • 初始登录过程和实际获取数据之间需要执行的步骤更少
  • \n
  • 无需后端数据库,可以在每次请求时重新发送令牌
  • \n
\n\n

缺点:

\n\n
    \n
  • 前端(浏览器)可以访问 Google access_token,这似乎没有必要,并且是一个潜在的安全问题
  • \n
  • 将 access_token 从 FE 传递到 BE 似乎是一个奇怪的过程,纯粹是为了允许 BE 然后使用该令牌发出另一个请求
  • \n
  • 我不确定我们如何刷新/更新令牌,因为我知道在客户端上存储刷新令牌是不好的做法。如果用户必须频繁登录才能重新连接帐户,这将不是一个好的用户体验
  • \n
\n\n

选项 2:授权代码流程 - 所有与 Google 的通信均通过 BE,令牌存储在 BE 数据库中

\n\n

选项2

\n\n

优点:

\n\n
    \n
  • 允许访问用户自己的数据
  • \n
  • 除了代码请求/同意页面之外,与 Google 的所有通信都是在后端实现的,因此在客户端上无法访问令牌
  • \n
  • 可以从 BE 使用客户端密钥
  • \n
\n\n

缺点:

\n\n
    \n
  • 流程更复杂,需要额外的步骤
  • \n
  • 鉴于 BE 是无状态的,目前尚不清楚如何最好地存储令牌。似乎需要将它们存储在数据库中,这是额外的复杂性,并且似乎会产生安全隐患 - 您将如何正确保护/加密所述数据库中的 access_token/refresh_tokens ?
  • \n
\n\n

结论

\n\n

鉴于数据处理发生在后端,选项 2 似乎稍微更合适,因为敏感令牌可以对前端应用程序隐藏,并且多个客户端(Web 前端、移动应用程序)参与该过程的义务较少初始登录/用户同意的例外情况。但是我\xe2\x80\x99m 不确定拥有一个充满用户身份验证令牌的数据库是否是一个好主意,或者我不确定如何正确保护该数据库。

\n

pin*_*yid 3

好消息是,这两种选择都完全有效并且同样安全。对浏览器中存在的短期访问令牌的担忧不是问题。同样,如果您只在 BE 上持有令牌,那么您将需要实现自己的客户端身份验证/会话/JWT 等等,这会带来相同的攻击面。

我已经完成了这两件事,目前正在从 BE 迁移到 FE。就我而言,原因是我需要做的一切都可以在 FE 上完成,所以我最终根本没有 BE。这并不完全正确,因为我通过 BE 进行了一些入职/付款,但仅此而已。

因此,最好的方法取决于您问题之外的因素,例如应用程序的性质、BE 成本是多少以及它的重要性、维护两个环境的 DevOps 技能组是什么样的、无论如何需要 BE 到什么程度,与完全可选。