【问题标题】:OAuth flow for third party API access第三方 API 访问的 OAuth 流程
【发布时间】:2019-10-09 21:58:24
【问题描述】:

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

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

起点

作为起点,假设我们有一个网络应用程序,其结构如下:

  • 前端 - SPA (Angular),由 AWS S3 + Cloudfront 托管
  • 后端 - 节点,作为无状态 AWS lambda 函数与 AWS API Gateway 一起运行
  • Auth0 用于处理 auth/signin 等。前端使用隐式 OAuth2 流来获取 access_tokens,它们存储在本地存储中,并作为标头包含在对后端的所有请求中。
  • 也可能是原生移动应用,使用相同的后端 API。

目标

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

问题陈述

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

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

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

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

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

以下是我对两种可能方法的解释。非常感谢您的想法/更正。

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

优点:

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

缺点:

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

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

优点:

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

缺点:

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

结论

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

【问题讨论】:

    标签: authentication oauth oauth-2.0 google-oauth google-sheets-api


    【解决方案1】:

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

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

    因此,最佳方法取决于您问题之外的因素,例如应用程序的性质、BE 成本是多少以及它的重要性、您的 devops 技能组合对于维护两个环境的外观、BE 的程度无论如何都是必需的,而不是完全可选的。

    【讨论】:

    • 感谢您的回复@pinoyyid。您列出的所有因素都是有道理的,当然值得考虑这些事情。我认为在我的案例中,在后端拥有大部分业务逻辑的吸引力是双重的——第一,它创建了一个清晰的关注点分离,第二,它允许多个客户端共享共同的业务逻辑。在 FE 上存储令牌时,如您所说,access_tokens 可能是短暂的,因此这些问题不太重要,但我很好奇您将如何处理这些令牌的更新,因为根据我的阅读,不建议在 FE 中存储刷新令牌。
    • Google 的 FE 隐式流程允许在没有用户干预的情况下获取访问令牌(假设用户登录到他的帐户)。所以我有一个隐藏的 iframe,它每小时将自己重定向到 Oauth 以获取新令牌。 Google JS 库 (gapi) 做同样的事情,但我拒绝使用封闭源代码,所以我推出了自己的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 2020-10-13
    • 2020-03-31
    相关资源
    最近更新 更多