OAuth 2.0
OAuth 2.0 是一个授权协议,它允许 API 客户端有限地访问 Web 服务器上的用户数据。GitHub、Google 和 Facebook 的 API 尤其使用它。OAuth 依赖于称为流程的认证场景,这些场景允许资源所有者(用户)在不共享其凭据的情况下共享来自资源服务器的受保护内容。为此,OAuth 2.0 服务器颁发访问令牌,客户端应用程序可以使用这些令牌代表资源所有者访问受保护资源。有关 OAuth 2.0 的更多信息,请参阅 oauth.net 和 RFC 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 scheme2components:3 securitySchemes:4 oAuthSample: # <---- arbitrary name5 type: oauth26 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/authorize10 scopes:11 read_pets: read your pets12 write_pets: modify pets in your account13
14# Step 2 - apply security globally...15security:16 - oAuthSample:17 - write_pets18 - read_pets19
20# ... or to individual operations21paths:22 /pets:23 patch:24 summary: Add a new pet25 security:26 - oAuthSample:27 - write_pets28 - read_pets29 ...
关键字 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 访问令牌都可以带有多个范围标签。范围是访问权限,它控制用户提供的凭据是否允许对资源服务器执行所需调用。它们不授予客户端除其已拥有权限之外的任何额外权限。注意:在授权码和隐式流程中,请求的范围列在向用户显示的授权表单上。要应用范围,您需要执行两个步骤:
- 在
components/securitySchemes
部分的 OAuth 安全定义中定义所有支持的范围。
1components:2 securitySchemes:3 oAuthSample:4 type: oauth25 flows:6 implicit:7 authorizationUrl: https://api.example.com/oauth2/authorize8 scopes:9 read_pets: read pets in your account10 write_pets: modify pets in your account
- 在该操作的
security
部分中列出每个操作所需的范围。
1paths:2 /pets/{petId}:3 patch:4 summary: Updates a pet in the store5 security:6 - oAuthSample: [write_pets]7 ...
如果所有 API 操作都需要相同的范围,您可以在 API 定义的根级别添加 security
。
1security:2 - oAuthSample: [write_pets]
无范围
范围是可选的,您的 API 可能不使用任何范围。在这种情况下,在范围定义中指定一个空对象 {}
,并在 security
部分中指定一个空范围列表 []
。
1components:2 securitySchemes:3 oAuthNoScopes:4 type: oauth25 flows:6 implicit:7 authorizationUrl: https://api.example.com/oauth2/authorize8 scopes: {} # <-----9
10security:11 - oAuthNoScopes: [] # <-----
相对端点 URL
在 OpenAPI 3.0 中,authorizationUrl
、tokenUrl
和 refreshUrl
可以相对于 API 服务器 URL 指定。如果这些端点与其余 API 操作位于同一服务器上,则这很方便。
1servers:2 - url: https://api.example.com/v23
4components:5 securitySchemes:6 oauth2sample:7 type: oauth28 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
流程使用 authorizationUrl
、tokenUrl
和可选的 refreshUrl
。以下是 Slack API 的一个示例:
1components:2 securitySchemes:3 oAuth2AuthCode:4 type: oauth25 description: For more information, see https://api.slack.com/docs/oauth6 flows:7 authorizationCode:8 authorizationUrl: https://slack.com/oauth/authorize9 tokenUrl: https://slack.com/api/oauth.access10 scopes:11 users:read: Read user information12 users:write: Modify user information13 im:read: Read messages14 im:write: Write messages15 im:history: Access the message archive16 search:read: Search messages, files, and so on17 # etc.
隐式流程
implicit
流程定义了 authorizationUrl
,用于从授权服务器获取访问令牌。以下是一个示例:
1components:2 securitySchemes:3 oAuth2Implicit:4 type: oauth25 description: For more information, see https://developers.getbase.com/docs/rest/articles/oauth2/requests6 flows:7 implicit:8 authorizationUrl: https://api.getbase.com/oauth2/authorize9 scopes:10 read: Grant read-only access to all your data except for the account and user info11 write: Grant write-only access to all your data except for the account and user info12 profile: Grant read-only access to the account and user info only
资源所有者密码流程
password
流程使用 tokenUrl
和可选的 refreshUrl
。以下是一个示例:
1components:2 securitySchemes:3 oAuth2Password:4 type: oauth25 description: See https://developers.getbase.com/docs/rest/articles/oauth2/requests6 flows:7 password:8 tokenUrl: https://api.getbase.com/oauth2/token9 scopes:10 read: Grant read-only access to all your data except for the account and user info11 write: Grant write-only access to all your data except for the account and user info12 profile: Grant read-only access to the account and user info only
客户端凭据流程
clientCredentials
流程使用 tokenUrl
和可选的 refreshUrl
。以下是 Getty Images API 的一个示例:
1components:2 securitySchemes:3 oAuth2ClientCredentials:4 type: oauth25 description: See http://developers.gettyimages.com/api/docs/v3/oauth2.html6 flows:7 clientCredentials:8 tokenUrl: https://api.gettyimages.com/oauth2/token/9 scopes: {} # Getty Images does not use scopes
多流程
下面是一个支持多个流程的 OAuth 2.0 安全定义示例。客户端可以使用其中任何一个流程。
1components:2 securitySchemes:3 oAuth2:4 type: oauth25 description: For more information, see https://developers.getbase.com/docs/rest/articles/oauth2/requests6 flows:7 implicit:8 authorizationUrl: https://api.getbase.com/oauth2/authorize9 scopes:10 read: Grant read-only access to all your data except for the account and user info11 write: Grant write-only access to all your data except for the account and user info12 profile: Grant read-only access to the account and user info only13 password:14 tokenUrl: https://api.getbase.com/oauth2/token15 scopes:16 read: Grant read-only access to all your data except for the account and user info17 write: Grant write-only access to all your data except for the account and user info18 profile: Grant read-only access to the account and user info only
常见问题
我是否需要额外将 authorizationUrl
和 tokenUrl
定义为 API 操作?
authorizationUrl
不是一个 API 端点,而是一个需要用户输入的特殊网页。因此,它无法使用 OpenAPI 进行描述。不过,如果需要,您可以描述 tokenUrl
。
authorizationUrl
和 tokenUrl
是否应包含查询字符串参数,例如 grant_type
、client_id
等?
OpenAPI 规范没有对此进行规定,因此取决于您和您使用的工具。