45

使用 oAuth 2.0,在“authorization-code”授权授予中,我首先调用“/authorize”,获取代码,然后在调用“/token”中使用此代码来获取访问令牌。

我的问题:为什么这是流程?我想这是出于安全原因,但我无法弄清楚。为什么是这样实现的,而不是在第一次调用(“/authorize”)后立即获得访问令牌?

为什么我们需要这个代码?

4

6 回答 6

20

是否也可以通过此中间步骤阻止客户端查看访问令牌?

来自 O'Reilly 的书:

授权代码此授权类型最适合服务器端 Web 应用程序。在资源所有者授权访问他们的数据后,他们将被重定向回 Web 应用程序,并使用授权代码作为 URL 中的查询参数。客户端应用程序必须将此代码交换为访问令牌。这种交换是服务器到服务器完成的,并且需要 client_id 和 client_secret,甚至阻止资源所有者获取访问令牌。此授权类型还允许使用刷新令牌对 API 进行长期访问。

基于浏览器的客户端应用程序的隐式授权 隐式授权是所有流程中最简单的,并且针对在浏览器中运行的客户端 Web 应用程序进行了优化。资源所有者授予对应用程序的访问权限,然后立即生成新的访问令牌并使用 URL 中的 #hash 片段将其传递回应用程序。应用程序可以立即从哈希片段中提取访问令牌(使用 JavaScript)并发出 API 请求。这种授权类型不需要中间的“授权代码”,但它也不会为长期访问提供可用的刷新令牌。

更新 - 确实是:

什么时候应该使用授权码流?授权码流程应在以下情况下使用

  • 需要长期访问。

  • OAuth 客户端是一个 Web 应用程序服务器。

  • API 调用的问责制非常重要,并且 OAuth 令牌不应该泄露给用户可以访问它的浏览器。

更多的:

也许最重要的是——因为访问令牌永远不会通过浏览器发送——访问令牌通过浏览器历史记录、引用标头、JavaScript 等泄露给恶意代码的风险较小。

于 2013-04-17T00:05:48.360 回答
13

授权码流适用于涉及 3 方的场景。

这些政党是:

  • 客户

    用户使用他的网络浏览器。他想使用你的应用程序。

  • 提供者

    有关于用户的信息。如果有人想访问这些数据,用户必须先同意。

  • 您的(网络)应用程序

    想要从提供商处访问有关用户的信息。

现在您的应用程序用户说(将他的浏览器重定向到/authorize端点):

嘿用户,这是我的客户 ID。请与提供者交谈,并允许他直接与我交谈。

因此,用户与提供者对话(请求授权码并通过在浏览器中打开您的回调 URL 将其返回给您的应用程序):

嘿供应商,我想使用这个应用程序,所以他们需要访问我的数据。给我一些代码,我将此代码提供给应用程序。

现在您的应用程序具有客户端提供者已知的授权代码。通过将其交给提供商,您的应用现在可以证明客户端允许它访问他的数据。提供商现在向您的(网络)应用程序颁发访问令牌,因此您的(网络)应用程序不必每次都重做这些步骤(至少在一段时间内)。

如果您的应用程序直接在客户端运行(例如 iPhone/Android 应用程序或 Javascript 客户端)的其他应用程序类型,则中间步骤是多余的。

于 2013-03-06T20:45:12.603 回答
11

客户端的数据通常被认为是不安全的。在初始步骤本身授予令牌的隐式调用的情况下,任何拥有 access_token 的人都可以请求数据,API 不知道谁在调用该 API。

但是,对于应用程序想要标识自己的 Web 服务器应用程序,带有 client_secret 的 client_id 与 authentication_code 一起发送以获取 access_token,将来可以独立发送。

假设,如果 access_token 最初是自己授予的,那么 client_id 和 access_token 仍然会被认为是公开的,所以应用程序必须每次都发送 client_secret 和 access_token 以确保请求确实来自它。

而在当前场景下,获取access_token后,可以独立进行进一步的请求,而不需要client_secret。

于 2015-09-23T14:24:02.173 回答
2

我认为是这样的;

当我们使用授权码时,我们有2个验证部分;

  • 1个;验证用户的所有权,因为他登录
  • 2;我们知道客户确实是他所说的那个人,因为客户正在发送他的 client_secret。

因此,如果我们在用户进行身份验证时返回访问令牌而不是授权码,我们知道是用户请求它,但我们不知道它将用于注册的客户端。例如,您的网络应用程序。

当我们使用“隐式授权”时;(或返回访问令牌而不是授权码)

  • 1个;我们知道接收访问令牌的是用户,但不需要获取授权码,因为基于“用户代理”的应用程序是不可检查的。如果您考虑一下,它是可以检查的,但它对每个人都可用。client_secret 在基于“用户代理”的应用程序的源代码中是公开可见的,因此每个人都可以“查看源代码”并复制 client_secret 并使用此方法来验证客户端的所有权。
于 2017-10-13T22:02:02.977 回答
1

重要的一点是

也许最重要的是——因为访问令牌永远不会通过浏览器发送——访问令牌通过浏览器历史记录、引用标头、JavaScript 等泄露给恶意代码的风险较小。

于 2014-07-18T12:51:27.683 回答
1

@ksht 的回答基本上是正确的。对于那些寻找简单、简短答案的人来说,它是这样的:

因为客户端应用程序(浏览器或本机应用程序)可以拦截传递的令牌。oauth隐式流程确实允许这样做,但仅在非常特定的情况下。在所有其他情况下,浏览器可能会泄漏信息(操作系统中的黑客攻击、浏览器错误、插件),或者对于本机应用程序,您可以拦截将重定向 url 映射到应用程序的自定义 url 方案。因此,解决方法是发回代码而不是令牌(通过 tls)并使用 PKCE 确保代码可以安全地交换为令牌。

于 2021-04-25T05:45:39.017 回答