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 规范中没有对此进行说明,因此这取决于您和您使用的工具。