您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

为什么 2023 年 OAuth 仍然很难

时间:2023-05-16 12:25:21  来源:51CTO  作者:

作者 | Robin Guldener

策划 | 言征

OAuth 是一个标准协议。基本上你可以想象的每种编程语言都有 OAuth 2.0 的客户端库。

但有了客户端库,却并不意味着万事大吉,如果你能够在大约 10 分钟内做到为任何 API 实施 OAuth。或者至少在一个小时内,请给我们发电子邮件——我们想请你吃一顿美味的晚餐,并听听你是怎么做到的。

1、50 个 OAuth 实践:结果一团糟

我们为 50 个最流行的 API 实现了 OAuth,例如 google(GmAIl、Calendar、Sheets 等)、HubSpot、Shopify、Salesforce、Stripe、Jira、Slack、Microsoft(Azure、Outlook、OneDrive)、LinkedIn、Facebook 和其他 OAuth API等。

我们的结论:现实世界的 OAuth 体验可与 2008 年的 JAVAScript 浏览器 API 相媲美。人们普遍认为应该如何做事,但实际上每个 API 都有自己对标准、实现怪癖以及非标准行为和扩展的解释. 结果:到处都是坑。

2、OAuth 标准太大太复杂

“这个 API 也使用 OAuth 2.0,我们几周前就已经这样做了。我应该在明天之前完成。”

——实习生的著名遗言

OAuth 是一个非常大的标准。OAuth 2.0 的官方网站目前列出了 17 个不同的 RFC(定义标准的文档),它们共同定义了 OAuth 2 的工作方式。它们涵盖了从 OAuth 框架和 Bearer 令牌到威胁模型和私钥 JWT 的所有内容。

“但是,”我听到你说,“肯定不是所有这些 RFC 都与使用 API 的简单第三方访问令牌授权相关吗?”

你说得对。让我们只关注可能与典型的 API 第三方访问用例相关的事情:

OAuth 标准:OAuth 2.0 现在是默认的,但是 OAuth 1.0a 仍然被一些人使用(2.1 即将到来)。一旦你知道你的 API 使用了哪一个,请继续。

授予类型:你需要authorization_code、client_credentials还是device_code?它们的作用是什么,你应该在什么时候使用它们?如有疑问,请尝试authorization_code。

旁注:刷新令牌也是一种授权类型,但有点特殊。它们的工作方式是标准化的,但你最初要求它们的方式却不是。稍后会详细介绍。

现在你已准备好处理你的请求,让我们看看许多(准确地说是 72 个)具有定义的含义和行为的官方 OAuth 参数。常见示例有prompt、scope、audience、resource、assertion和login_hint。然而,根据我们的经验,大多数 API 提供者似乎都没有注意到这个列表,就像你可能直到现在一样,所以不要太担心它。

如果你认为这仍然感觉太复杂并且需要学习很多东西,我们倾向于同意你的看法。

大多数构建公共 API 的团队似乎也同意这一点。他们没有实现完整的 OAuth 2.0 子集,而是只实现了他们认为 API 用例所需的 OAuth 部分。这导致文档中有相当长的页面概述了 OAuth 如何为这个特定的 API 工作。但是我们很难责怪他们;他们的 DX 只考虑最好的意图。如果他们真的试图实施完整的标准,你需要阅读一本小书!

Salesforce authorization_code OAuth 流程。为什么不喜欢这个简单的 10 步过程的清晰视觉效果?

图片

问题在于每个人对于 OAuth 的哪个子集与他们相关的想法略有不同,因此你最终会得到许多不同的(子)实现。

3、每个人的 OAuth 都有细微差别

由于每个 API 都实现了不同的 OAuth 子集,你很快就会陷入被迫详细阅读 OAuth 文档的长页的情况:

他们在授权调用中需要哪些参数?

  • 对于 Jira,audience参数是 key(并且必须设置为特定的固定值)。谷歌更喜欢通过不同的范围来处理这个问题,但真正关心的是提示参数。同时,Microsoft 的某个人发现了response_mode参数并要求你始终将其设置为query。
  • Notion API 采用了一种激进的方法,取消了无处不在的范围参数。事实上,你甚至不会在他们的 API 文档中找到“作用域”这个词。Notion 将它们称为“功能”,你可以在注册应用程序时设置它们。我们花了 30 分钟才明白发生了什么。他们为什么要重新发明这个轮子?
  • 使用offline_access会变得更糟:现在大多数 API 都会在短时间后过期访问令牌。要获得刷新令牌,你需要请求“offline_access”,这需要通过参数、范围或你在注册 OAuth 应用程序时设置的内容来完成。有关详细信息,请咨询你的 API 或 OAuth 医生。

他们希望在令牌请求调用中看到什么?

  • 某些 API,如 Fitbit,坚持在标头中获取数据。大多数人真的希望它在正文中,编码为x-www-url-form-encoded,除了少数,例如 Notion,它更喜欢将它作为 JSON 获取。
  • 有些人希望你使用基本身份验证来验证此请求。许多人对此并不在意。但要小心,他们明天可能会改变主意。

我应该在哪里重定向我的用户进行授权?

  • Shopify 和 Zendesk 有一个模型,在该模型中,每个用户都会获得一个子域,例如 {subdomain}.myshopify.com。是的,它包括 OAuth 授权页面,因此你最好将动态 URL 构建到你的模型和前端代码中。
  • Zoho Books 为不同地点的客户提供不同的数据中心。希望他们记住他们的数据所在的位置:要授权你的应用程序,你的美国客户应该访问 https://accounts.zoho.com,欧洲人可以访问 https://accounts.zoho.eu,欢迎印度人访问 https://账户.zoho.in. 清单还在继续。

但至少我可以选择我的回调 URL,不是吗?

如果你输入http://localhost:3003/callback作为 Slack API 的回调,他们会友善地提醒你“请使用 https 确保安全”。是的,也适用于本地主机。幸运的是,在 localhost 上有 OAuth 重定向的解决方案。

我们可以继续讨论很长时间,但我们认为你现在可能明白了。

图片

  • OAuth 太复杂;让我们制作一个更简单的 OAuth 版本,它拥有我们需要的一切!XKCD

4、许多 API 向 OAuth 添加非标准扩展

尽管 OAuth 标准非常庞大,但许多 API 似乎仍然在其中寻找所需功能的差距。我们看到的一个常见问题是,除了access_token之外,你还需要一些数据才能使用 API。如果这些额外的数据可以与 OAuth 流中的 access_token 一起返回给你,那不是很好吗?

我们实际上认为这是一个好主意——或者至少比强迫用户在之后执行古怪的额外 API 请求来获取此信息(看看你,Jira)要好。但这确实意味着你特别需要为每个 API 实现更多非标准行为。

以下是我们见过的一小部分非标准扩展:

  • Quickbooks 使用realmID,你需要在每个 API 请求中传入它。他们唯一一次告诉你这个realmID是作为 OAuth 回调中的附加参数。最好将它存放在安全的地方!
  • Braintree 对companyID做同样的事情
  • Salesforce 为每个客户使用不同的 API 基本 URL;他们称之为instance_url。值得庆幸的是,他们在令牌响应中返回了用户的instance_url和访问令牌,但你确实需要从那里解析并存储它。
  • 不幸的是,Salesforce 还做了更烦人的事情:访问令牌在预设时间后过期,这可以由用户自定义。到目前为止还不错,但出于某种原因,当你刚收到的访问令牌将过期时,他们不会在令牌响应中告诉你(其他人都会这样做)。相反,你需要查询额外的令牌详细信息端点以获取令牌的(当前)到期日期。为什么,Salesforce,为什么?
  • Slack 有两种不同类型的范围:你作为 Slack 机器人拥有的范围和允许你代表授权你的应用程序的用户采取行动的范围。很聪明,但他们并没有为每个范围添加不同的范围,而是实现了一个单独的user_scopes参数,你需要在授权调用中传递该参数。你最好了解这一点,祝你好运,在你的 OAuth 库中找到对此的支持。

为了简洁起见,我们将跳过我们遇到的许多非真正标准的 OAuth 流程。

5、“invalid_request”调试 OAuth 流程很困难

调试分布式系统总是很困难。当你使用的服务使用广泛的、通用的错误消息时,这会变得更加困难。

OAuth2 有标准化的错误消息,但它们在告诉你正在发生的事情方面与上面标题中的示例一样有用(顺便说一下,这是 OAuth 标准推荐的错误消息之一)。

你可能会争辩说 OAuth 是一个标准并且每个 API 都有文档,那么有什么可以调试的呢?

很多。我无法告诉你文档出错的频率。或者缺少一个细节。或者还没有更新最新的变化。或者当你第一次看到它们时你错过了什么。我们实施的 80% 的 OAuth 流程在首次实施时都存在一些问题,需要调试。

在我调试 OAuth 流程时 Randall 是如何观察我的?XKCD

某些流程也会因看似随机的原因而中断:例如,如果你传入 PKCE 参数,LinkedIn OAuth 就会中断。你得到的错误?“客户端错误 - 无效的 OAuth 请求。” 那是……告诉?我们花了一个小时才明白传递(可选,通常被忽略)PKCE 参数是中断流程的原因。

另一个常见错误是发送的范围与你在应用程序中预注册的范围不匹配。(预注册范围?是的,现在很多 API 都需要这样做。)这通常会导致出现有关范围存在问题的一般错误消息。呃。

6、在 API 之上构建的繁琐审批

事实是,如果你通过使用他们的 API 构建其他系统,你可能处于较弱的位置。你的客户要求集成,因为他们已经在使用其他系统。现在你需要让他们开心。

公平地说,许多 API 都是自由的,并为开发人员提供简单的自助服务注册流程来注册他们的应用程序并开始使用 OAuth。但是一些最流行的 API 在你的应用程序公开并且可以被任何用户使用之前需要进行审查。同样,公平地说,大多数审核过程都很正常,可以在几天内完成。就最终用户的安全性和质量而言,它们可能是净收益。

但一些臭名昭著的例子可能需要数月才能完成,有些甚至需要你签订收入分成协议:

  • 如果你想访问包含更敏感的用户数据(例如电子邮件内容)的范围,Google 需要进行“安全审查”。我们听说这些审核可能需要数天或数周才能通过,并且你需要付出大量的工作。
  • 想要与 Rippling 集成?准备好接受他们的 30 多个问题和安全预生产筛选。我们听说访问需要几个月的时间(如果你获得批准)。
  • HubSpot、Notion、Atlassian、Shopify 以及几乎所有其他拥有集成市场或应用程序商店的人都需要经过审查才能在其中列出。有些评论很温和,有些则要求你提供演示登录、视频演练、博客文章(是的!)等等。但是,在市场或商店中列出通常是可选的。
  • Ramp、Brex、Twitter 和许多其他公司没有面向开发人员的自助注册流程,需要你填写表格以进行手动访问。许多人很快就能处理请求,但我们仍在等待数周后的回复。
  • Xero 是货币化 API 的一个特别极端的例子:如果你想超过 25 个连接帐户的限制,你必须成为 Xero 合作伙伴并将你的应用程序列在他们的应用程序商店中。然后,他们将从该商店产生的每条线索中(截至撰写本文时)收取 15% 的收入。

7、OAuth 安全性很棘手并且是一个动态变化的目标

随着攻击被发现,可用的 Web 技术不断发展,OAuth 标准也发生了变化。如果你希望实施当前的安全最佳实践,OAuth 工作组为你提供了一份相当冗长的指南。如果你使用的 API 目前仍在使用 OAuth 1.0a,你就会意识到向后兼容性是一场永无止境的斗争。

幸运的是,安全性随着每次迭代而变得更好,但这通常是以开发人员的更多工作为代价的。即将推出的 OAuth 2.1 标准将使一些当前的最佳实践成为强制性的,包括强制性的 PKCE(目前只有少数 API 需要这个)和对刷新令牌的额外限制。

图片

至少 OAuth 已经实现了双因素身份验证模型。XKCD

随着访问令牌的过期和刷新令牌的兴起,可能已经迎来了最大的变化。从表面上看,这个过程似乎很简单:每当访问令牌过期时,用刷新令牌刷新它并存储新的访问令牌和刷新令牌。

实际上,当我们实现这个时,我们必须考虑:

  • 竞争条件:我们如何确保在刷新当前访问令牌时没有其他请求运行?
  • 如果你在一定天数内未使用刷新令牌(或者如果用户已撤销访问权限),某些 API 也会使刷新令牌过期。预计一些刷新会失败。
  • 某些 API 会在每次刷新请求时向你发出一个新的刷新令牌……
  • 但有些人也默默地假设你会保留旧的刷新令牌并继续使用它。
  • 一些 API 会以绝对值告诉你访问令牌过期时间。其他人只是相对“从现在开始的几秒钟”。还有一些,例如 Salesforce,不会轻易泄露此类信息。

8、最后:还没有谈到的事情

遗憾的是,我们只是触及了 OAuth 实施的皮毛而已。现在,OAuth 流程已经运行并且获得了访问令牌,这时候需要考虑:

  • 如何安全地存储这些访问令牌和刷新令牌。它们就像你用户帐户的密码。但是散列不是一种选择;你需要安全、可逆的加密。
  • 检查授予的范围是否与请求的范围匹配(某些 API 允许用户更改他们在授权流程中授予的范围)。
  • 刷新令牌时避免竞争条件。
  • 在提供商端,检测用户撤销的访问令牌。
  • 让用户知道访问令牌已过期,以便他们可以在需要时重新授权你的应用程序。
  • 如何撤销你不再需要的访问令牌(或用户要求你根据 GDPR 删除的访问令牌)。
  • 可用 OAuth 范围的更改、提供程序错误、缺少文档等。

原文链接:https://www.nango.dev/blog/why-is-oauth-still-hard



Tags:OAuth   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
都 2023 年了,OAuth 为什么还是让人头疼?
【编者按】这篇文章介绍了 OAuth 的实践中的问题,如:OAuth 标准过于庞大和复杂、每个人的 OAuth 都有细微的不同、许多 API 在 OAuth 中添加了非标准的扩展、 调试 OAuth 很难...【详细内容】
2023-07-11  Search: OAuth  点击:(245)  评论:(0)  加入收藏
为什么 2023 年 OAuth 仍然很难
作者 | Robin Guldener策划 | 言征OAuth 是一个标准协议。基本上你可以想象的每种编程语言都有 OAuth 2.0 的客户端库。但有了客户端库,却并不意味着万事大吉,如果你能够在大...【详细内容】
2023-05-16  Search: OAuth  点击:(428)  评论:(0)  加入收藏
由Raycast to flomo了解到OAuth 2.0之PKCE
五一期间在flomo官网的扩展中心看到了这个Raycast to flomo,对Mac上的效率工具有了点了解,我直接基本都没有用过Mac自带的spotlight。。。 我好奇的不是竟然可以用这种方式发...【详细内容】
2022-05-05  Search: OAuth  点击:(343)  评论:(0)  加入收藏
OAuth 2.0 与 OpenID Connect 协议的完整指南
本文由 Haseeb Anwar 发表在 medium,经原作者授权由 InfoQ 中文站翻译并分享。我们都在网站或者手机应用中见过“谷歌登陆”和“绑定 Facebook“这样的按钮。如果你点击这个...【详细内容】
2020-07-16  Search: OAuth  点击:(318)  评论:(0)  加入收藏
什么是 OAuth 2.0 授权码模式?
授权码模式大概是我们所最常见的OAuth 2.0 授权模式。当用户授权给app时,授权码模式就会在网页应用和原生apps中使用到。...【详细内容】
2019-08-01  Search: OAuth  点击:(1229)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(6)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(13)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(9)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(11)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(9)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(6)  评论:(0)  加入收藏
站内最新
站内热门
站内头条