# 授权 OAuth 应用

你可以允许其他用户授权 OAuth app。

> \[!NOTE]
> 请考虑构建GitHub App，而不是OAuth app。
>
> OAuth apps 和 GitHub Apps 均使用 OAuth 2.0。
>
> GitHub Apps 可以代表用户（类似于 OAuth app或自己）执行操作，这对于不需要用户输入的自动化有利。 此外， GitHub Apps 使用细粒度的权限，让用户可以更好地控制应用可以访问的存储库，并使用生存期较短的令牌。 有关详细信息，请参阅 [GitHub 应用和 OAuth 应用之间的差异](/zh/enterprise-cloud@latest/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps) 和 [关于创建GitHub应用](/zh/enterprise-cloud@latest/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps)。

GitHub 的 OAuth 实现支持标准的 [授权码授权类型](https://tools.ietf.org/html/rfc6749#section-4.1) 以及适用于无法访问 Web 浏览器的应用的 OAuth 2.0 [设备授权授予](https://tools.ietf.org/html/rfc8628)。

如果想跳过以标准方式授权应用（例如在测试应用时），可以使用[非 Web 应用程序流](#non-web-application-flow)。

要为您的 OAuth app 授权，请考虑哪种授权流程最适合您的应用。

* [Web 应用程序流](#web-application-flow)：用于授权用户在浏览器中运行的标准 OAuth apps 。 （不支持[隐式授权类型](https://tools.ietf.org/html/rfc6749#section-4.2)。）
* [设备流](#device-flow)：用于无外设应用，例如 CLI 工具。

> \[!NOTE] 本文包含使用 `github.com` 域的命令或示例。 可以在其他域（例如 `GitHub`）中访问 octocorp.ghe.com。

## 即将过期的访问令牌

若要强制定期轮换令牌并减少已泄露令牌的影响，可以将你的 OAuth app 配置为获取会过期的访问令牌。 当应用使用过期的访问令牌时，你还将收到包含访问令牌的刷新令牌。 Web 应用程序流和设备流都支持过期令牌。

访问令牌会在 8 小时后过期，而刷新令牌会在连续 6 个月未使用后过期。 可以使用刷新令牌生成新的访问令牌和新的刷新令牌。 有关详细信息，请参阅 [使用刷新令牌刷新访问令牌](#refreshing-an-access-token-with-a-refresh-token)。

### 在运行时选择启用会过期的令牌

若要测试并逐步推出对将要过期的令牌的支持，您可以请求 `offline_access` 范围以及你的其他范围来选择接收将要过期令牌和刷新令牌以用于单次登录。 请求 `offline_access` 范围时，即使应用未配置为使用过期令牌，也会收到即将过期的访问令牌和刷新令牌。

如果您的应用同时支持 GitHub Enterprise Server 和 `offline_access`，则应做好 GitHub.com 作用域可能不起作用的准备，因为 GitHub Enterprise Server 实例可能尚不支持过期令牌。 在这种情况下，你将收到一个未过期的令牌，并且不会收到刷新令牌，因此你的应用不应假定始终返回刷新令牌。

### 要求你的应用使用有时效的令牌

更新应用以使用刷新令牌来处理令牌过期后，可以全局强制应用令牌过期。 这将导致所有新令牌在签发时都带有过期时间和刷新令牌。 启用此功能不会导致现有令牌过期 ， 它们将继续生存期较长。 如果要切换到即将过期的令牌，请让用户再次登录。 若要为应用配置此设置，请参阅 [激活 OAuth 应用的可选功能](/zh/enterprise-cloud@latest/apps/oauth-apps/maintaining-oauth-apps/activating-optional-features-for-oauth-apps)。

## Web 应用程序流程

> \[!NOTE]
> 如果要生成GitHub应用，仍可使用 OAuth Web 应用程序流，但设置有一些重要差异。 有关详细信息，请参阅“[代表用户使用 GitHub 应用进行身份验证](/zh/enterprise-cloud@latest/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-with-a-github-app-on-behalf-of-a-user)”。

为您的应用授权用户的 Web 应用流程是：

1. 用户将被重定向以请求其GitHub标识
2. 用户通过GitHub重定向回您的网站
3. 您的应用程序使用用户的访问令牌访问 API

### 1.请求用户的GitHub标识

```
GET https://github.com/login/oauth/authorize
```

此终结点采用以下输入参数。

| 查询参数                                                                                                | 类型       | 必需？   | 说明                                                                                                                                                                                                                                                                                                                                          |
| --------------------------------------------------------------------------------------------------- | -------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id`                                                                                         | `string` | 必需的   | 你在[注册](https://github.com/settings/applications/new)时从GitHub收到的客户端ID。                                                                                                                                                                                                                                                                       |
| `redirect_uri`                                                                                      | `string` | 强烈建议  | 用户获得授权后被发送到的应用程序中的 URL。 请参阅以下有关[重定向 URL](#redirect-urls) 的详细信息。                                                                                                                                                                                                                                                                             |
| `login`                                                                                             | `string` | 可选    | 提供用于登录和授权应用程序的特定账户。                                                                                                                                                                                                                                                                                                                         |
| `scope`                                                                                             | `string` | 上下文相关 | 一个由空格分隔的[范围](/zh/enterprise-cloud@latest/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)列表。 如果未提供，则 `scope` 对于未为应用程序授权任何范围的用户默认为空列表。 对于已向应用程序授权作用域的用户，不会显示含作用域列表的 OAuth 授权页面。 相反，通过用户向应用程序授权的作用域集，此流程步骤将自动完成。 例如，如果用户已经执行了两次 Web 流，并且已授权一个具有 `user` 范围的令牌和另一个具有 `repo` 范围的令牌，则不提供 `scope` 的第三个 Web 流将收到具有 `user` 和 `repo` 范围的令牌。 |
| 使用 `offline_access`作用域来获取会过期的令牌，不会改变该作用域的行为——系统不会像跟踪 `repo` 或 `user` 这类常规作用域那样跟踪它，因此使用它时也不会触发额外的提示。 |          |       |                                                                                                                                                                                                                                                                                                                                             |
| `state`                                                                                             | `string` | 强烈建议  | 不可猜测的随机字符串。 它用于防止跨站请求伪造攻击。                                                                                                                                                                                                                                                                                                                  |
|                                                                                                     |          |       |                                                                                                                                                                                                                                                                                                                                             |
| `code_challenge`                                                                                    | `string` | 强烈建议  | 用于使用 PKCE（代码交换的证明密钥）保护身份验证流。 如果包含 `code_challenge_method`，则需要。 必须是客户端生成的随机字符串，包含 43 个字符且为 SHA-256 哈希值。 有关此安全扩展的更多详细信息，请参阅 [PKCE RFC](https://datatracker.ietf.org/doc/html/rfc7636)。                                                                                                                                                        |
| `code_challenge_method`                                                                             | `string` | 强烈建议  | 用于使用 PKCE（代码交换的证明密钥）保护身份验证流。 如果包含 `code_challenge`，则需要。 必须是 `S256` - `plain` 不支持代码质询方法。                                                                                                                                                                                                                                                     |
|                                                                                                     |          |       |                                                                                                                                                                                                                                                                                                                                             |
| `allow_signup`                                                                                      | `string` | 可选    | 是否向未经身份验证的用户提供了在 OAuth 流期间注册GitHub的选项。 默认值为 `true`。 在策略禁止注册时使用 `false`。                                                                                                                                                                                                                                                                     |
| `prompt`                                                                                            | `string` | 可选    | 强制帐户选取器在设置为 `select_account` 时显示。 如果应用程序具有非 HTTP 重定向 URI，或者用户登录了多个帐户，则帐户选取器也会显示。                                                                                                                                                                                                                                                            |

目前不支持 CORS 预检请求 (OPTIONS)。

### 2. 用户被GitHub重定向回您的网站

如果用户接受你的请求，GitHub 会使用代码参数中的临时 `code` 以及你在上一步的 `state` 参数中提供的状态重定向回你的站点。 临时代码将在 10 分钟后到期。 如果状态不匹配，然后第三方创建了请求，您应该中止此过程。

将此 `code` 交换为访问令牌：

```
POST https://github.com/login/oauth/access_token
```

此终结点采用以下输入参数。

| 参数名称            | 类型       | 必需？  | 说明                                                                                                                                                                   |
| --------------- | -------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id`     | `string` | 必需的  | 从 GitHub 中针对 OAuth app 接收的客户端 ID。                                                                                                                                    |
| `client_secret` | `string` | 必需的  | 你从 GitHub 收到的用于您的 OAuth app 的客户端密钥。                                                                                                                                  |
| `code`          | `string` | 必需的  | 您收到的代码是作为对步骤 1 的响应。                                                                                                                                                  |
| `redirect_uri`  | `string` | 强烈建议 | 用户获得授权后将被发送到的应用程序 URL。 我们可以使用此参数来匹配发放 `code` 时最初提供的 URI，以防止对服务的攻击。                                                                                                   |
|                 |          |      |                                                                                                                                                                      |
| `code_verifier` | `string` | 强烈建议 | 用于使用 PKCE（代码交换的证明密钥）保护身份验证流。 如果`code_challenge`在用户授权期间发送，则是必需的。 必须是用于在授权请求中生成 `code_challenge` 的原始值。 这可以与 `state` 参数一起存储在 Cookie 中，也可以在身份验证期间存储在会话变量中，具体取决于应用程序体系结构。 |
|                 |          |      |                                                                                                                                                                      |

默认情况下，响应采用以下形式：

```shell
access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a
&scope=repo%2Cgist
&token_type=bearer
```

如果在 `Accept` 标头中提供格式，则还可以接收不同格式的响应。 例如 `Accept: application/json` 或 `Accept: application/xml`：

```json
Accept: application/json
{
  "access_token":"gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "scope":"repo,gist",
  "token_type":"bearer"
}
```

```xml
Accept: application/xml
<OAuth>
  <token_type>bearer</token_type>
  <scope>repo,gist</scope>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
</OAuth>
```

如果你的 OAuth app 使用会过期的访问令牌，或者你请求了 `offline_access` 范围，则响应还会包含一个 `refresh_token`，以及 `expires_in` 和 `refresh_token_expires_in` 值，用于指示每个令牌何时过期（以从当前时刻起的秒数表示）。 有关详细信息，请参阅 [“即将过期的访问令牌](#expiring-access-tokens)”。

默认情况下，响应采用以下形式：

```shell
access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a
&expires_in=28800
&refresh_token=ghr_1B4a2e77838347a7E420ce178F2E7c6912E169246c34E1ccbF66C46812d16D5B1A9Dc86A1498
&refresh_token_expires_in=15897600
&scope=repo%2Cgist
&token_type=bearer
```

### 3. 使用访问令牌访问 API

访问令牌可用于代表用户向 API 提出请求。

```
Authorization: Bearer OAUTH-TOKEN
GET https://api.github.com/user
```

例如，您可以像以下这样在 curl 中设置“授权”标头：

```shell
curl -H "Authorization: Bearer OAUTH-TOKEN" https://api.github.com/user
```

每次收到访问令牌时，都应使用该令牌重新验证用户的标识。 当你向他们发送邮件授权应用时，用户可以更改他们登录的帐户，如果在每次登录后没有验证用户的标识，则可能会出现混合用户数据的风险。

## 设备流动

设备流允许你授权用户使用无头应用程序，例如 CLI 工具或 [Git 凭据管理器](https://github.com/git-ecosystem/git-credential-manager)。

在使用设备流识别和授权用户之前，必须先在应用的设置中启用它。 有关在应用中启用设备流的详细信息，请参阅针对 [](/zh/enterprise-cloud@latest/apps/maintaining-github-apps/modifying-a-github-app-registration) 的 GitHub Apps 以及针对 [](/zh/enterprise-cloud@latest/apps/oauth-apps/maintaining-oauth-apps/modifying-an-oauth-app) 的 OAuth apps。

### 设备流程概述

1. 您的应用程序会请求设备和用户验证码，并获取用户将在其中输入用户验证码的授权 URL。
2. 应用提示用户输入用户验证码  [`https://github.com/login/device`](https://github.com/login/device)。
3. 应用程序轮询用户的身份验证状态。 用户授权设备后，应用程序将能够使用新的访问令牌进行 API 调用。

### 步骤 1：应用从GitHub请求设备和用户验证码

```
POST https://github.com/login/device/code
```

您的应用程序必须请求用户验证码和验证 URL，因为应用程序在下一步中提示用户进行身份验证时将使用它们。 此请求还返回设备验证代码，应用程序必须使用它们来接收访问令牌和检查用户身份验证的状态。

终结点采用以下输入参数。

| 参数名称                             | 类型       | 说明                                                                                                                                     |
| -------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id`                      | `string` |                                                                                                                                        |
| **必填。** 从 GitHub 中针对应用接收的客户端 ID。 |          |                                                                                                                                        |
| `scope`                          | `string` | 应用请求访问的范围的列表（以空格分隔）。 有关详细信息，请参阅“[OAuth 应用的范围](/zh/enterprise-cloud@latest/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)”。 |

默认情况下，响应采用以下形式：

```shell
device_code=3584d83530557fdd1f46af8289938c8ef79f9dc5
&expires_in=900
&interval=5
&user_code=WDJB-MJHT
&verification_uri=https%3A%2F%2Fgithub.com%2Flogin%2Fdevice
```

| 参数名称                                                    | 类型        | 说明                                                                                                                                                              |
| ------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `device_code`                                           | `string`  | 设备验证码为 40 个字符，用于验证设备。                                                                                                                                           |
| `user_code`                                             | `string`  | 用户验证码显示在设备上，以便用户可以在浏览器中输入该代码。 此代码为 8 个字符，中间有连字符。                                                                                                                |
| `verification_uri`                                      | `string`  | 用户需要输入 `user_code` 的验证 URL： [`https://github.com/login/device`](https://github.com/login/device)。                                                               |
| `expires_in`                                            | `integer` |                                                                                                                                                                 |
| `device_code` 和 `user_code` 过期之前的秒数。 默认值为 900 秒或 15 分钟。 |           |                                                                                                                                                                 |
| `interval`                                              | `integer` | 在能够发出新的访问令牌请求 (`POST https://github.com/login/oauth/access_token`) 以完成设备授权之前必须经过的最短秒数。 例如，如果间隔为 5，则只有经过 5 秒后才能发出新请求。 如果在 5 秒内发出多个请求，则将达到速率限制并收到 `slow_down` 错误。 |

如果在 `Accept` 标头中提供格式，则还可以接收不同格式的响应。 例如 `Accept: application/json` 或 `Accept: application/xml`：

```json
Accept: application/json
{
  "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://github.com/login/device",
  "expires_in": 900,
  "interval": 5
}
```

```xml
Accept: application/xml
<OAuth>
  <device_code>3584d83530557fdd1f46af8289938c8ef79f9dc5</device_code>
  <user_code>WDJB-MJHT</user_code>
  <verification_uri>https://github.com/login/device</verification_uri>
  <expires_in>900</expires_in>
  <interval>5</interval>
</OAuth>
```

### 第 2 步：提示用户在浏览器中输入用户代码

你的设备将显示用户验证码，并提示用户输入代码  [`https://github.com/login/device`](https://github.com/login/device)。

### 步骤 3：应用程序通过轮询 GitHub 来检查用户是否已授权设备。

```
POST https://github.com/login/oauth/access_token
```

应用将发出轮询 `POST https://github.com/login/oauth/access_token` 的设备授权请求，直到设备和用户代码过期，或者用户已使用有效的用户代码成功授权应用。 应用必须使用在步骤 1 中检索到的最短轮询 `interval`，以免出现速率限制错误。 有关详细信息，请参阅[设备流的速率限制](#rate-limits-for-the-device-flow)。

用户必须在 15 分钟（或 900 秒内）内输入有效代码。 15 分钟后，需要使用 `POST https://github.com/login/device/code` 请求新的设备授权代码。

一旦用户授权， 应用程序将收到一个访问令牌，该令牌可用于代表用户向 API 发出请求。

终结点采用以下输入参数。

| 参数名称                                                                         | 类型       | 说明 |
| ---------------------------------------------------------------------------- | -------- | -- |
| `client_id`                                                                  | `string` |    |
| **必填。** 从 GitHub 中针对 OAuth app 接收的客户端 ID。                                    |          |    |
| `device_code`                                                                | `string` |    |
| **必填。** 你从 `device_code` 请求中收到的 `POST https://github.com/login/device/code`。 |          |    |
| `grant_type`                                                                 | `string` |    |
| **必填。** 授权类型必须是 `urn:ietf:params:oauth:grant-type:device_code`。              |          |    |

默认情况下，响应采用以下形式：

```shell
access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a
&token_type=bearer
&scope=repo%2Cgist
```

如果在 `Accept` 标头中提供格式，则还可以接收不同格式的响应。 例如 `Accept: application/json` 或 `Accept: application/xml`：

```json
Accept: application/json
{
 "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "token_type": "bearer",
  "scope": "repo,gist"
}
```

```xml
Accept: application/xml
<OAuth>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
  <token_type>bearer</token_type>
  <scope>gist,repo</scope>
</OAuth>
```

如果你的OAuth app使用会过期的访问令牌，或者你请求了`offline_access`范围，则响应还会包含一个`refresh_token`，以及用于指示每个令牌何时过期的`expires_in`和`refresh_token_expires_in`值。 有关详细信息，请参阅 [“即将过期的访问令牌](#expiring-access-tokens)”。

```shell
access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a
&expires_in=28800
&refresh_token=ghr_1B4a2e77838347a7E420ce178F2E7c6912E169246c34E1ccbF66C46812d16D5B1A9Dc86A1498
&refresh_token_expires_in=15897600
&token_type=bearer
&scope=repo%2Cgist
```

### 设备流的速率限制

当用户在浏览器上提交验证码时，每个应用程序在一个小时内的提交速率限制为 50 个。

如果在请求之间所需的最小时间范围（即 `POST https://github.com/login/oauth/access_token`）内发出多个访问令牌请求 (`interval`)，你将达到速率限制，并收到 `slow_down` 错误响应。
`slow_down` 错误响应向上一个 `interval` 添加 5 秒钟的时间。 有关详细信息，请参阅[设备流的错误代码](#error-codes-for-the-device-flow)。

### 设备流的错误代码

| 错误代码                           | 说明                                                                                                                                                                                                                                |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authorization_pending`        | 授权请求待处理并且用户尚未输入用户代码时，将发生此错误。 应用应在不超出 `POST https://github.com/login/oauth/access_token` 的情况下继续轮询 `interval` 请求，这需要每个请求之间的最短秒数。                                                                                                    |
| `slow_down`                    | 收到 `slow_down` 错误时，会使用 `interval` 向请求之间所需的最短 `POST https://github.com/login/oauth/access_token` 或时间范围添加 5 秒钟的额外时间。 例如，如果请求之间的启动间隔至少需要 5 秒，并且你收到了 `slow_down` 错误响应，那么现在必须等待至少 10 秒，然后才能发出新的 OAuth 访问令牌请求。 错误响应包括必须使用的新 `interval`。 |
| `expired_token`                | 如果设备代码已过期，则将看到 `token_expired` 错误。 您必须发出新的设备代码请求。                                                                                                                                                                                 |
| `unsupported_grant_type`       | 轮询 OAuth 令牌请求 `urn:ietf:params:oauth:grant-type:device_code` 时，授权类型必须为 `POST https://github.com/login/oauth/access_token` 并且必须作为输入参数包含在内。                                                                                         |
| `incorrect_client_credentials` | 对于设备流，您必须传递应用程序的客户端 ID，该 ID 可以在应用程序的设置页面上找到。 设备流不需要 `client_secret`。                                                                                                                                                              |
| `incorrect_device_code`        | 提供的 device\_code 无效。                                                                                                                                                                                                              |
| `access_denied`                | 当用户在授权过程中单击取消时，你将收到 `access_denied` 错误，该用户将无法再次使用验证码。                                                                                                                                                                             |
| `device_flow_disabled`         | 尚未在应用的设置中启用设备流。 有关详细信息，请参阅[设备流](#device-flow)。                                                                                                                                                                                    |

有关详细信息，请参阅 [OAuth 2.0 设备授权](https://tools.ietf.org/html/rfc8628#section-3.5)。

## 使用刷新令牌刷新访问令牌

如果 OAuth app 使用将要过期的访问令牌，则可以使用刷新令牌生成新的访问令牌和新的刷新令牌。 使用刷新令牌后，该刷新令牌和旧的访问令牌将不再有效。 有关过期令牌的详细信息，请参阅 [“即将过期的访问令牌](#expiring-access-tokens)”。

如果您的刷新令牌在使用前已过期，则必须再次引导用户完成 Web 应用流程或设备流程，以获取新的令牌对。

若要刷新访问令牌，请向以下 URL 发出 `POST` 请求，以及下面的输入参数。

```
POST https://github.com/login/oauth/access_token
```

| 参数名称            | 类型       | 必需？               | 说明                                  |
| --------------- | -------- | ----------------- | ----------------------------------- |
| `client_id`     | `string` | 必需的               | 从 GitHub 中针对 OAuth app 接收的客户端 ID。   |
| `client_secret` | `string` | 必填，除非该令牌是使用设备流生成的 | 你从 GitHub 收到的用于您的 OAuth app 的客户端密钥。 |
| `grant_type`    | `string` | 必需的               | 值必须是 `refresh_token`。               |
| `refresh_token` | `string` | 必需的               | 生成访问令牌时收到的刷新令牌。                     |

默认情况下，响应采用以下形式：

```shell
access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a
&expires_in=28800
&refresh_token=ghr_1B4a2e77838347a7E420ce178F2E7c6912E169246c34E1ccbF66C46812d16D5B1A9Dc86A1498
&refresh_token_expires_in=15897600
&scope=repo%2Cgist
&token_type=bearer
```

新访问令牌上的作用域将与上一个令牌的范围匹配。 在刷新令牌期间，您不能传入 `scope` 参数来更改生成的令牌的访问权限。

如果你指定的刷新令牌无效或已过期，你将收到 `bad_refresh_token` 错误。 若要解决此错误，请再次通过 Web 应用程序流或设备流发送用户以获取新的访问令牌和刷新令牌。

## 非 Web 应用程序流程

非 web 身份验证适用于测试等有限的情况。 如果需要，您可以使用[基本身份验证](/zh/enterprise-cloud@latest/rest/authentication/authenticating-to-the-rest-api#using-basic-authentication)，通过您的 [personal access token 设置页面](/zh/enterprise-cloud@latest/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)创建 personal access token。 此方法支持用户随时撤销访问权限。

## 重定向 URL

`redirect_uri` 参数是可选的。 如果省略，GitHub 会将用户重定向到在 OAuth app 中配置的第一个回调 URL
设置。

如果需要，可以为回调 URL 启用通配符匹配。 启用通配符匹配后，重定向 URL 的主机（不包括子域）和端口必须与回调 URL 完全匹配，重定向 URL 的路径必须引用回调 URL 的子目录。 这意味着回调 URL 的任何子域或子目录都将匹配，并作为回调 URL 允许。 例如，如果对回调 URL `https://example.com/path` 启用了通配符匹配：

```
CALLBACK: https://example.com/path

MATCH: https://example.com/path
MATCH: https://example.com/path/subdir/other
MATCH: https://oauth.example.com/path
MATCH: https://oauth.example.com/path/subdir/other
FAIL:  https://example.com/bar
FAIL:  https://example.com/
FAIL:  https://example.com:8080/path
FAIL:  https://oauth.example.com:8080/path
FAIL:  https://example.org
```

禁用通配符匹配后，重定向 URL 必须与回调 URL 完全匹配。 您可以在应用设置中为每个回调 URL 启用或禁用通配符匹配。

> \[!WARNING]
> 启用通配符匹配可能会使应用面临安全风险，因为它允许攻击者将授权代码发送到回调 URL 的任何子域或子目录。 仅当您绝对需要启用通配符匹配，并且完全确定自己能够控制回调 URL 的所有可能子域和路径时，才启用该功能。 有关详细信息，请参阅 [OAuth 2.0 安全最佳做法](https://www.rfc-editor.org/info/rfc9700/#section-4.1.1-11)。

在2026 年 8 月 3 日 之前已启用单个回调 URL 的应用，其回调 URL 已启用通配符匹配。 这保留了在通配符匹配成为可配置设置之前就已存在的重定向行为，这也就是为什么在该日期之前创建的所有 OAuth apps 和部分 GitHub Apps 都启用了通配符匹配。 如果你的应用不需要通配符匹配，我们建议你禁用它。

### 环回重定向网址

可选的 `redirect_uri` 参数还可用于环回 URL，这对于在台式计算机上运行的本机应用程序非常实用。 如果应用程序指定了环回 URL 和端口，那么在授权应用程序后，用户将被重定向到提供的 URL 和端口。
`redirect_uri` 不需要与应用的回叫 URL 中指定的端口匹配。

对于 `http://127.0.0.1/path` 回调 URL，如果应用程序正在端口 `redirect_uri` 上进行侦听，则可以使用此 `1234`：

```http
http://127.0.0.1:1234/path
```

请注意，OAuth RFC [建议不要使用 `localhost`](https://datatracker.ietf.org/doc/html/rfc8252#section-7.3)，而是使用环回文本 `127.0.0.1` 或 IPv6 `::1`。

## 创建多个 OAuth apps 令牌

您可以为用户/应用程序/作用域组合创建多个令牌，以便为特定用例创建令牌。

如果你的OAuth app支持一种使用 GitHub 登录且只需要基本用户信息的工作流，这会很有用。 另一个工作流程可能需要访问用户的私有仓库。 通过使用多个令牌，您的 OAuth app 可以针对每个用例执行 Web 流程，并且只请求所需的作用域。 如果用户仅使用你的应用程序进行登录，就绝不会被要求授予你的 OAuth app 对其私有仓库的访问权限。

每个用户/应用程序/作用域组合签发的令牌数量有限，速率限制是每小时创建十个令牌。 如果应用程序为同一用户和同一作用域创建 10 个以上的令牌， GitHub 则撤消具有相同用户/应用程序/范围组合的现有令牌之一，顺序如下：

1. 从未使用过的最早令牌，该令牌是在一分钟前创建的。 在最后一分钟创建的令牌通常受到保护，以便应用程序有时间使用它刚刚创建的令牌。
2. 如果没有此类令牌，但至少使用了一个令牌，则使用最近最少的令牌。
3. 如果从未使用过令牌，则为最早的令牌，即使它在最后一分钟内创建。

达到每小时速率限制不会撤销最早的令牌。 相反，它会在浏览器中触发重新授权提示，要求用户仔细检查他们向你的应用授予的权限。 此提示旨在中断应用陷入的任何潜在的无限循环，因为应用几乎没有理由在一小时内向用户请求十个令牌。

> \[!WARNING]
> 从 OAuth app 撤销所有权限将会删除应用程序代表用户生成的所有 SSH 密钥，包括[部署密钥](/zh/enterprise-cloud@latest/authentication/connecting-to-github-with-ssh/managing-deploy-keys#deploy-keys)。

## 指示用户审查其访问权限

可以链接到授权 OAuth app 信息，以便用户可以查看和撤销其应用程序授权。

若要生成此链接，需要使用在注册应用程序时从 GitHub 收到的 OAuth app 的 `client_id`。

```http
https://github.com/settings/connections/applications/:client_id
```

> \[!TIP]
> 要详细了解您的 OAuth app 可为用户访问的资源，请参阅 [为用户发现资源](/zh/enterprise-cloud@latest/rest/guides/discovering-resources-for-a-user)。

## 故障排除

* [排查授权请求错误](/zh/enterprise-cloud@latest/apps/oauth-apps/maintaining-oauth-apps/troubleshooting-authorization-request-errors)
* [排查 OAuth 应用访问令牌请求错误](/zh/enterprise-cloud@latest/apps/oauth-apps/maintaining-oauth-apps/troubleshooting-oauth-app-access-token-request-errors)
* [设备流错误](#error-codes-for-the-device-flow)
* [令牌过期和吊销](/zh/enterprise-cloud@latest/authentication/keeping-your-account-and-data-secure/token-expiration-and-revocation)

## 其他阅读材料

* [关于 GitHub 的身份验证](/zh/enterprise-cloud@latest/authentication/keeping-your-account-and-data-secure/about-authentication-to-github)