🔑 GIF 动画中解释的 OAuth 2.0 流程

2025-05-24

🔑 GIF 动画中解释的 OAuth 2.0 流程

在本文中,我们将使用简洁易懂的 GIF 动图来介绍所有 OAuth 2.0 流程。这篇文章也可以作为日后参考的速查表!

注意:如果您已经了解 OAuth,请随意直接跳到流程。


等等,什么是 OAuth❓

OAuth(开放授权)允许第三方网站或应用访问用户数据,而无需用户共享凭据。它是一组规则,用于实现访问委托。用户可以授权应用访问哪些资源,并相应地限制访问权限。

术语🧱

现在我们知道了 OAuth 的含义,在深入研究之前让我们快速了解一下术语。

学期 描述
客户端📦 请求访问资源的应用程序。通常是第三方。
资源所有者👤 拥有资源的用户。它也可以是一台机器🤖(例如企业场景)。
资源🖼 可以是图像、通过 API 公开的数据等等。
资源服务器📚 托管受保护资源的服务器。通常,如果提供了正确的令牌,则 API 服务器会提供资源。
授权服务器 服务器负责授权客户端并颁发访问令牌。
用户代理🌐 资源所有者通过浏览器或移动应用程序与我们的授权服务器进行通信。
访问令牌🔑 授权成功后颁发的令牌。访问令牌可针对一组权限(范围)获取,并具有预定的有效期,超过有效期即失效。
刷新令牌🔄 一种特殊类型的令牌,可用于补充访问令牌。

现在,让我们根据示例(1)在抽象的 OAuth 流程中关联这些术语。

最终用户(资源所有者👤)授权打印服务(应用程序📦)访问其托管在照片共享服务(资源服务器📚)中的照片(资源🖼),无需共享用户名和密码。相反,他们直接向照片共享服务信任的服务器(授权服务器🛡)进行身份验证,该服务器会向打印服务颁发委托专用凭证(访问令牌🔑)。

请注意,我们的应用(客户端)首先必须在授权服务器中注册。注册完成后,会返回一个客户端 ID。此外,还会根据具体场景生成一个客户端密钥(可选)。此密钥只有授权服务器和应用程序知道。

好了,理论讲得够多了!现在来看看一些 GIF 动图,了解授权场景/流程!


OAuth 2.0 中的流程

  1. 授权码授予
  2. 使用 PKCE 授予授权码
  3. 客户端凭证授予
  4. 资源所有者密码凭证授予
  5. 隐性授予

1.授权码授予流程

这是 Web 和移动应用常用的基于浏览器的授权流程。您可以直接将其与上述示例联系起来。在下图中,该流程从客户端开始,将用户重定向到授权端点。

1 授权码授予流程 - 保密客户端

此流程针对机密客户端进行了优化。机密客户端是能够保证 保密性的应用client_secret。此流程的一部分发生在前端通道(直到获取授权码)。如您所见,access_token🔑 交换步骤通过后端通道(服务器到服务器通信)以保密方式进行。

现在您可能自然会想,“那么公共客户呢?!”

2. 使用 PKCE 进行授权码授予

使用授权码授权流程的公共客户端存在安全隐患。无论是单页 JS 应用还是原生移动应用,client_secret由于整个源代码均可访问(通过 DevTools 或应用反编译),因此无法隐藏授权码。此外,在具有自定义 URI 方案的原生应用中,恶意应用有可能通过类似的重定向 URI 拦截授权码。

为了解决这个问题,授权码授予流程使用了代码交换证明密钥 (PKCE)。这可以在运行时生成一个密钥,授权服务器可以安全地验证该密钥。那么它是如何工作的呢?

2.1. 转换 - 遇见 SHA256

客户端会生成一个名为Code Verifier(CV) 的随机字符串。将Code transformation method(CM) 应用于 CV 以派生出Code Challenge(CC) ✨ 目前,有两种转换方法plainS256(SHA-256)

2.1 授权码授予流程 - PKCE - SHA256 如何工作?

在简单的变换中,CC 等于 CV。出于明显的安全原因,不建议这样做,因此建议使用 S256。SHA256 是一个哈希函数。从高层次上讲,它接受输入数据并输出一个字符串。但是,这个输出字符串有一些特殊之处:

  • 此字符串对于输入数据是唯一的,输入中的任何更改都会导致不同的输出字符串!可以说,它是输入数据的签名。
  • 输入数据无法从字符串中恢复,并且它是一个单向函数(参考上面的 GIF)。
  • 输出字符串是固定长度的。

2.2. 我们如何从代码验证器(CV)生成代码挑战(CC)?

2.2 授权码授予流程 - PKCE - 什么是代码挑战与代码验证器

你可能已经猜到了。看一下这张图,理解如何从 CV 生成 CC。在本例中,由于使用了 SHA256,所以无法从 CC 生成 CV(记住,这是单向转换)。只能从 CV 生成 CC(假设转换方法已知——S256在我们的例子中)。

PKCE流

请注意,流程从首先生成的 CV 和 CC 开始,替换client_secret

使用 PKCE 授予授权码

现在我们已经了解了 CV 和 CC 是如何生成的,让我们来看看完整的流程。大部分部分与授权码授予流程类似。CV 和 CC 在流程开始之前就已经生成。最初,只需传递 CC 和 CM 即可获取授权码。获取授权码后,CV 将被发送以获取访问令牌。

为了确认合法性,授权服务器会对收到的 CV 应用转换方法(CM,即 SHA256),并将其与之前获取的CC 进行比较。如果匹配,则会提供令牌!请注意,即使有人截获了授权码,也无法获取 CV。由于单向函数的特性,CV 无法从 CC 中恢复。此外,由于 CV 仅在运行时生成,因此无法从源代码或通过反编译找到它!

3. 客户端凭证授予流程

在上述流程中,资源所有者(用户)必须提供同意。也存在并非每次都需要用户授权的情况。例如机器间通信(或应用间通信)。在这种情况下,客户端本质上是保密的,应用可能需要代表自身而非用户行事。

4 客户端凭证授予

而且,这是所有流程中最简单的。

4. 资源所有者密码凭证授予流程

此流程仅用于资源所有者与客户端之间高度信任的情况。如您所见,最初会从 RO 获取用户名和密码,并用于获取access_token。获取令牌后,用户名和密码详细信息将被丢弃。

3 资源所有者密码凭证授予

此流程不推荐用于现代应用程序,通常仅用于遗留或迁移目的。与其他流程相比,它具有更高的风险,因为它遵循了 OAuth 想要避免的密码反模式!

5. 隐式授权流程

官方不再推荐此流程!隐式授权曾被认为是公共客户端授权码授权的替代方案。正如您所注意到的,公共客户端不包含授权码授权,client_secret并且不涉及任何反向通道。实际上,访问令牌是在获得同意后立即获取的。

5 隐性授予

然而,令牌是通过 URL 片段(以 开头#)传递的,该片段永远不会通过网络发送到重定向 URL。相反,该片段部分由前端加载的脚本访问(重定向的结果)。脚本access_token将以这种方式提取 ,并进行后续调用以获取资源。正如您已经看到的,此流程容易受到访问令牌泄漏和重放攻击。

建议使用授权码授予或任何其他合适的授予类型,而不是隐式授予类型


希望这篇文章对您有所帮助。您可以查阅RFC 6749RFC 7636,深入了解每个流程的具体步骤。

欢迎分享你的想法。如果觉得有用,别忘了分享这篇文章哦🚀

告诉我你接下来想在 GIF 系列中看到什么!在那之前,请继续保持 OAuthsome 的风格!✨


文章来源:https://dev.to/hem/oauth-2-0-flows-explained-in-gifs-2o7a
PREV
像我五岁一样解释 Redux
NEXT
🚀 [GIF] Javascript Promise API 方法速查表 - Promise.all、Promise.allSettled、Promise.race、Promise.any 它们是如何组织的?Promise.resolve Promise.reject Promise.all Promise.allSettled Promise.race Promise.any Javascript 动图 🎉