跳到内容

OAuth 2.0

OAuth 2.0 是一个授权协议,它允许 API 客户端有限地访问 Web 服务器上的用户数据。GitHub、Google 和 Facebook 的 API 尤其使用它。OAuth 依赖于称为流程的认证场景,这些场景允许资源所有者(用户)在不共享其凭据的情况下共享来自资源服务器的受保护内容。为此,OAuth 2.0 服务器颁发访问令牌,客户端应用程序可以使用这些令牌代表资源所有者访问受保护资源。有关 OAuth 2.0 的更多信息,请参阅 oauth.netRFC 6749

流程

这些流程(也称为授权类型)是 API 客户端从授权服务器获取访问令牌所执行的场景。OAuth 2.0 提供了几种适用于不同类型 API 客户端的流程

  • 授权码 – 最常见的流程,主要用于服务器端和移动 Web 应用程序。此流程类似于用户使用其 Facebook 或 Google 帐户注册 Web 应用程序的方式。
  • 隐式 – 此流程要求客户端直接检索访问令牌。当用户的凭据无法存储在客户端代码中时(因为它们很容易被第三方访问),此流程会很有用。它适用于不包含任何服务器组件的 Web、桌面和移动应用程序。
  • 资源所有者密码凭据(或简称密码)– 需要使用用户名和密码登录。由于在这种情况下凭据将成为请求的一部分,因此此流程仅适用于受信任的客户端(例如,API 提供商发布的官方应用程序)。
  • 客户端凭据 – 旨在用于服务器到服务器的认证,此流程描述了一种客户端应用程序代表自身而非任何单个用户行事的方法。在大多数场景中,此流程提供了一种方式,允许用户在客户端应用程序中指定其凭据,以便它可以访问客户端控制下的资源。

使用 OpenAPI 描述 OAuth 2.0

要描述受 OAuth 2.0 保护的 API,首先,将具有 type: oauth2 的安全方案添加到全局 components/securitySchemes 部分。然后添加 security 键以全局或针对单个操作应用安全。

1
# Step 1 - define the security scheme
2
components:
3
securitySchemes:
4
oAuthSample: # <---- arbitrary name
5
type: oauth2
6
description: This API uses OAuth 2 with the implicit grant flow. [More info](https://api.example.com/docs/auth)
7
flows:
8
implicit: # <---- OAuth flow(authorizationCode, implicit, password or clientCredentials)
9
authorizationUrl: https://api.example.com/oauth2/authorize
10
scopes:
11
read_pets: read your pets
12
write_pets: modify pets in your account
13
14
# Step 2 - apply security globally...
15
security:
16
- oAuthSample:
17
- write_pets
18
- read_pets
19
20
# ... or to individual operations
21
paths:
22
/pets:
23
patch:
24
summary: Add a new pet
25
security:
26
- oAuthSample:
27
- write_pets
28
- read_pets
29
...

关键字 flows 指定此 OAuth 2.0 方案支持的一个或多个命名流程。流程名称如下:

  • authorizationCode – 授权码流程(在 OpenAPI 2.0 中曾称为 accessCode
  • implicit – 隐式流程
  • password – 资源所有者密码流程
  • clientCredentials – 客户端凭据流程(在 OpenAPI 2.0 中曾称为 application

flows 对象可以指定多个流程,但每种类型只能有一个。每个流程包含以下信息:

字段名称 描述 适用于流程
authorizationCode implicit password clientCredentials
authorizationUrl 此流程使用的授权 URL。可以是相对于 API 服务器 URL 的相对路径。 + + - -
tokenUrl 此流程使用的令牌 URL。可以是相对于 API 服务器 URL 的相对路径。 + - + +
refreshUrl 可选。用于获取刷新令牌的 URL。可以是相对于 API 服务器 URL 的相对路径。 + + + +
scopes OAuth2 安全方案的可用范围。范围名称与其简短描述之间的映射。 + + + +

关于范围

借助 OpenAPI 3.0,用户可以授予对其账户的范围访问权限,这可能因客户端应用程序希望执行的操作而异。每个 OAuth 访问令牌都可以带有多个范围标签。范围是访问权限,它控制用户提供的凭据是否允许对资源服务器执行所需调用。它们不授予客户端除其已拥有权限之外的任何额外权限。注意:在授权码隐式流程中,请求的范围列在向用户显示的授权表单上。要应用范围,您需要执行两个步骤:

  1. components/securitySchemes 部分的 OAuth 安全定义中定义所有支持的范围。
1
components:
2
securitySchemes:
3
oAuthSample:
4
type: oauth2
5
flows:
6
implicit:
7
authorizationUrl: https://api.example.com/oauth2/authorize
8
scopes:
9
read_pets: read pets in your account
10
write_pets: modify pets in your account
  1. 在该操作的 security 部分中列出每个操作所需的范围。
1
paths:
2
/pets/{petId}:
3
patch:
4
summary: Updates a pet in the store
5
security:
6
- oAuthSample: [write_pets]
7
...

如果所有 API 操作都需要相同的范围,您可以在 API 定义的根级别添加 security

1
security:
2
- oAuthSample: [write_pets]

无范围

范围是可选的,您的 API 可能不使用任何范围。在这种情况下,在范围定义中指定一个空对象 {},并在 security 部分中指定一个空范围列表 []

1
components:
2
securitySchemes:
3
oAuthNoScopes:
4
type: oauth2
5
flows:
6
implicit:
7
authorizationUrl: https://api.example.com/oauth2/authorize
8
scopes: {} # <-----
9
10
security:
11
- oAuthNoScopes: [] # <-----

相对端点 URL

在 OpenAPI 3.0 中,authorizationUrltokenUrlrefreshUrl 可以相对于 API 服务器 URL 指定。如果这些端点与其余 API 操作位于同一服务器上,则这很方便。

1
servers:
2
- url: https://api.example.com/v2
3
4
components:
5
securitySchemes:
6
oauth2sample:
7
type: oauth2
8
flows:
9
authorizationCode:
10
authorizationUrl: /oauth/authorize # <-----
11
tokenUrl: /oauth/token # <-----
12
scopes: ...

相对 URL 根据 RFC 3986 解析。在上面的示例中,端点将解析为:

authorizationUrl: https://api.example.com/oauth/authorize

tokenUrl: https://api.example.com/oauth/token

安全方案示例

授权码流程

authorization 流程使用 authorizationUrltokenUrl 和可选的 refreshUrl。以下是 Slack API 的一个示例:

1
components:
2
securitySchemes:
3
oAuth2AuthCode:
4
type: oauth2
5
description: For more information, see https://api.slack.com/docs/oauth
6
flows:
7
authorizationCode:
8
authorizationUrl: https://slack.com/oauth/authorize
9
tokenUrl: https://slack.com/api/oauth.access
10
scopes:
11
users:read: Read user information
12
users:write: Modify user information
13
im:read: Read messages
14
im:write: Write messages
15
im:history: Access the message archive
16
search:read: Search messages, files, and so on
17
# etc.

隐式流程

implicit 流程定义了 authorizationUrl,用于从授权服务器获取访问令牌。以下是一个示例:

1
components:
2
securitySchemes:
3
oAuth2Implicit:
4
type: oauth2
5
description: For more information, see https://developers.getbase.com/docs/rest/articles/oauth2/requests
6
flows:
7
implicit:
8
authorizationUrl: https://api.getbase.com/oauth2/authorize
9
scopes:
10
read: Grant read-only access to all your data except for the account and user info
11
write: Grant write-only access to all your data except for the account and user info
12
profile: Grant read-only access to the account and user info only

资源所有者密码流程

password 流程使用 tokenUrl 和可选的 refreshUrl。以下是一个示例:

1
components:
2
securitySchemes:
3
oAuth2Password:
4
type: oauth2
5
description: See https://developers.getbase.com/docs/rest/articles/oauth2/requests
6
flows:
7
password:
8
tokenUrl: https://api.getbase.com/oauth2/token
9
scopes:
10
read: Grant read-only access to all your data except for the account and user info
11
write: Grant write-only access to all your data except for the account and user info
12
profile: Grant read-only access to the account and user info only

客户端凭据流程

clientCredentials 流程使用 tokenUrl 和可选的 refreshUrl。以下是 Getty Images API 的一个示例:

1
components:
2
securitySchemes:
3
oAuth2ClientCredentials:
4
type: oauth2
5
description: See http://developers.gettyimages.com/api/docs/v3/oauth2.html
6
flows:
7
clientCredentials:
8
tokenUrl: https://api.gettyimages.com/oauth2/token/
9
scopes: {} # Getty Images does not use scopes

多流程

下面是一个支持多个流程的 OAuth 2.0 安全定义示例。客户端可以使用其中任何一个流程。

1
components:
2
securitySchemes:
3
oAuth2:
4
type: oauth2
5
description: For more information, see https://developers.getbase.com/docs/rest/articles/oauth2/requests
6
flows:
7
implicit:
8
authorizationUrl: https://api.getbase.com/oauth2/authorize
9
scopes:
10
read: Grant read-only access to all your data except for the account and user info
11
write: Grant write-only access to all your data except for the account and user info
12
profile: Grant read-only access to the account and user info only
13
password:
14
tokenUrl: https://api.getbase.com/oauth2/token
15
scopes:
16
read: Grant read-only access to all your data except for the account and user info
17
write: Grant write-only access to all your data except for the account and user info
18
profile: Grant read-only access to the account and user info only

常见问题

我是否需要额外将 authorizationUrltokenUrl 定义为 API 操作?

authorizationUrl 不是一个 API 端点,而是一个需要用户输入的特殊网页。因此,它无法使用 OpenAPI 进行描述。不过,如果需要,您可以描述 tokenUrl

authorizationUrltokenUrl 是否应包含查询字符串参数,例如 grant_typeclient_id 等?

OpenAPI 规范没有对此进行规定,因此取决于您和您使用的工具。

没有找到您想要的内容?询问社区 发现错误?告诉我们

© . All rights reserved.