跳至主要内容

授权 OAuth 应用

您可以允许其他用户授权您的 OAuth 应用程序。

注意:请考虑构建 GitHub 应用程序而不是 OAuth 应用程序。

OAuth 应用程序和 GitHub 应用程序都使用 OAuth 2.0。

GitHub 应用程序可以代表用户执行操作,类似于 OAuth 应用程序,或者以自身身份执行操作,这对于不需要用户输入的自动化操作非常有用。此外,GitHub 应用程序使用细粒度权限,让用户可以更好地控制应用程序可以访问哪些存储库,并使用短期令牌。有关更多信息,请参阅 "GitHub 应用程序和 OAuth 应用程序之间的区别" 和 "关于创建 GitHub 应用程序"。

GitHub 的 OAuth 实现支持标准的 授权码授予类型 和 OAuth 2.0 设备授权授予,适用于无法访问 Web 浏览器的应用程序。

如果您想跳过以标准方式授权应用程序,例如在测试应用程序时,可以使用 非 Web 应用程序流程

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

网页应用流程

注意:如果您正在构建 GitHub 应用,您仍然可以使用 OAuth 网页应用流程,但设置有一些重要的区别。有关更多信息,请参阅“代表用户使用 GitHub 应用进行身份验证”。

授权用户使用您的应用的网页应用流程是

  1. 用户被重定向到请求他们的 GitHub 身份
  2. 用户被 GitHub 重定向回您的网站
  3. 您的应用使用用户的访问令牌访问 API

1. 请求用户的 GitHub 身份

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

此端点接受以下输入参数。

查询参数类型必需?描述
client_id字符串必需您在 注册 时从 GitHub 收到的客户端 ID。
redirect_uri字符串强烈建议授权后用户将被发送到的应用程序中的 URL。有关 重定向 URL 的详细信息,请参见下文。
login字符串可选建议使用特定帐户登录并授权应用。
scope字符串上下文相关一个空格分隔的 范围 列表。如果未提供,scope 默认为空列表,适用于未为应用程序授权任何范围的用户。对于已为应用程序授权范围的用户,用户不会看到包含范围列表的 OAuth 授权页面。相反,此流程步骤将自动完成,并使用用户已为应用程序授权的范围集。例如,如果用户已执行过两次网页流程,并已使用 user 范围授权了一个令牌,并使用 repo 范围授权了另一个令牌,则第三个未提供 scope 的网页流程将收到一个包含 userrepo 范围的令牌。
state字符串强烈建议一个不可猜测的随机字符串。它用于防止跨站点请求伪造攻击。
allow_signup字符串可选是否允许未经身份验证的用户在 OAuth 流程中选择注册 GitHub 帐户。默认值为 true。当策略禁止注册时,请使用 false
prompt字符串可选如果设置为 select_account,则强制显示帐户选择器。如果应用程序具有非 HTTP 重定向 URI 或用户已登录多个帐户,则也会显示帐户选择器。

目前不支持 PKCE(代码交换证明密钥)参数 code_challengecode_challenge_method。目前不支持 CORS 预检请求 (OPTIONS)。

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

如果用户接受您的请求,GitHub 会将用户重定向回您的网站,并在代码参数中提供一个临时的 code,以及在 state 参数中提供您在上一步中提供的状态。临时代码将在 10 分钟后过期。如果状态不匹配,则表示第三方创建了请求,您应该中止该过程。

将此 code 交换为访问令牌

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

此端点接受以下输入参数。

参数名称类型必需?描述
client_id字符串必需您从 GitHub 获取的 OAuth 应用程序的客户端 ID。
client_secret字符串必需您从 GitHub 获取的 OAuth 应用程序的客户端密钥。
code字符串必需您在步骤 1 中收到的代码。
redirect_uri字符串强烈建议用户授权后被发送到您应用程序中的 URL。我们可以使用它与最初在颁发 code 时提供的 URI 进行匹配,以防止对您服务的攻击。

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

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

如果您在 Accept 标头中提供格式,您也可以以不同的格式接收响应。例如,Accept: application/jsonAccept: application/xml

Accept: application/json
{
  "access_token":"gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "scope":"repo,gist",
  "token_type":"bearer"
}
Accept: application/xml
<OAuth>
  <token_type>bearer</token_type>
  <scope>repo,gist</scope>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
</OAuth>

3. 使用访问令牌访问 API

访问令牌允许您代表用户向 API 发出请求。

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

例如,在 curl 中,您可以像这样设置 Authorization 标头

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

每次您收到访问令牌时,都应该使用该令牌重新验证用户的身份。当您将用户发送到授权您的应用程序时,用户可以更改他们登录的帐户,如果您在每次登录后不验证用户的身份,您可能会混淆用户数据。

设备流程

设备流程允许您为无头应用程序(例如 CLI 工具或 Git Credential Manager)授权用户。

在您使用设备流程授权和识别用户之前,您必须先在应用程序设置中启用它。有关在应用程序中启用设备流程的更多信息,请参阅“修改 GitHub 应用程序注册”(适用于 GitHub 应用程序)和“修改 OAuth 应用程序”(适用于 OAuth 应用程序)。

设备流程概述

  1. 您的应用程序请求设备和用户验证代码,并获取授权 URL,用户将在该 URL 中输入用户验证代码。
  2. 该应用程序提示用户在 https://github.com/login/device 中输入用户验证代码。
  3. 该应用程序轮询用户身份验证状态。一旦用户授权了设备,该应用程序将能够使用新的访问令牌进行 API 调用。

步骤 1:应用程序从 GitHub 请求设备和用户验证代码

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

您的应用程序必须请求用户验证代码和验证 URL,该应用程序将在下一步中使用这些代码和 URL 提示用户进行身份验证。此请求还会返回设备验证代码,该代码必须由应用程序用于接收访问令牌并检查用户身份验证的状态。

该端点采用以下输入参数。

参数名称类型描述
client_id字符串必需。您从 GitHub 为您的应用程序收到的客户端 ID。
scope字符串您的应用程序请求访问的范围的空格分隔列表。有关更多信息,请参阅“OAuth 应用程序的范围”。

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

device_code=3584d83530557fdd1f46af8289938c8ef79f9dc5&expires_in=900&interval=5&user_code=WDJB-MJHT&verification_uri=https%3A%2F%2Fgithub.com%2Flogin%2Fdevice
参数名称类型描述
device_code字符串设备验证代码为 40 个字符,用于验证设备。
user_code字符串用户验证代码显示在设备上,以便用户可以在浏览器中输入该代码。此代码为 8 个字符,中间有一个连字符。
verification_uri字符串用户需要输入user_code的验证 URL:https://github.com/login/device
expires_in整数device_codeuser_code 过期前的秒数。默认值为 900 秒或 15 分钟。
interval整数您可以在完成设备授权之前发出新的访问令牌请求(POST https://github.com/login/oauth/access_token)的最短秒数。例如,如果间隔为 5,则您必须等待 5 秒才能发出新的请求。如果您在 5 秒内发出多个请求,则会遇到速率限制并收到 slow_down 错误。

如果您在 Accept 标头中提供格式,您也可以以不同的格式接收响应。例如,Accept: application/jsonAccept: application/xml

Accept: application/json
{
  "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://github.com/login/device",
  "expires_in": 900,
  "interval": 5
}
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 中输入代码。

步骤 3:应用程序轮询 GitHub 以检查用户是否授权了设备

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

您的应用程序将发出设备授权请求,轮询 POST https://github.com/login/oauth/access_token,直到设备和用户代码过期或用户已使用有效的用户代码成功授权应用程序。应用程序必须使用步骤 1 中检索到的最小轮询 interval 以避免速率限制错误。有关更多信息,请参阅“设备流的速率限制”。

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

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

该端点采用以下输入参数。

参数名称类型描述
client_id字符串必需。您从 GitHub 获取的 OAuth 应用程序的客户端 ID。
device_code字符串必需。您从 POST https://github.com/login/device/code 请求中收到的 device_code
grant_type字符串必需。授予类型必须为 urn:ietf:params:oauth:grant-type:device_code

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

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

如果您在 Accept 标头中提供格式,您也可以以不同的格式接收响应。例如,Accept: application/jsonAccept: application/xml

Accept: application/json
{
 "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "token_type": "bearer",
  "scope": "repo,gist"
}
Accept: application/xml
<OAuth>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
  <token_type>bearer</token_type>
  <scope>gist,repo</scope>
</OAuth>

设备流的速率限制

当用户在浏览器中提交验证代码时,每个应用程序每小时有 50 次提交的速率限制。

如果您在请求之间(或 interval)的必需最短时间内发出多个访问令牌请求(POST https://github.com/login/oauth/access_token),您将遇到速率限制并收到 slow_down 错误响应。slow_down 错误响应会将最后一个 interval 增加 5 秒。有关更多信息,请参阅 设备流的错误代码

设备流的错误代码

错误代码描述
授权待处理当授权请求处于待处理状态且用户尚未输入用户代码时,会发生此错误。应用程序应继续轮询POST https://github.com/login/oauth/access_token请求,但不能超过interval,这要求每个请求之间至少间隔一定秒数。
速度过慢当您收到slow_down错误时,将向使用POST https://github.com/login/oauth/access_token的请求之间的最小interval或时间间隔添加 5 秒。例如,如果初始间隔要求请求之间至少间隔 5 秒,并且您收到slow_down错误响应,则现在必须等待至少 10 秒才能发出新的 OAuth 访问令牌请求。错误响应包含您必须使用的新的interval
令牌已过期如果设备代码已过期,则您将看到token_expired错误。您必须发出新的设备代码请求。
不支持的授权类型授权类型必须为urn:ietf:params:oauth:grant-type:device_code,并在您轮询 OAuth 令牌请求POST https://github.com/login/oauth/access_token时作为输入参数包含在内。
不正确的客户端凭据对于设备流,您必须传递应用程序的客户端 ID,您可以在应用程序设置页面上找到它。设备流不需要client_secret
不正确的设备代码提供的设备代码无效。
拒绝访问当用户在授权过程中点击取消时,您将收到access_denied错误,并且用户将无法再次使用验证代码。
设备流已禁用应用程序设置中未启用设备流。有关更多信息,请参阅“设备流”。

有关更多信息,请参阅“OAuth 2.0 设备授权授予”。

非 Web 应用程序流

非 Web 身份验证仅适用于测试等有限情况。如果您需要,可以使用基本身份验证使用您的个人访问令牌设置页面创建个人访问令牌。此方法允许用户随时撤销访问权限。

重定向 URL

redirect_uri参数是可选的。如果省略,GitHub 将将用户重定向到 OAuth 应用程序设置中配置的回调 URL。如果提供,重定向 URL 的主机(不包括子域)和端口必须与回调 URL 完全匹配。重定向 URL 的路径必须引用回调 URL 的子目录。

CALLBACK: http://example.com/path

GOOD: http://example.com/path
GOOD: http://example.com/path/subdir/other
GOOD: http://oauth.example.com/path
GOOD: http://oauth.example.com/path/subdir/other
BAD:  http://example.com/bar
BAD:  http://example.com/
BAD:  http://example.com:8080/path
BAD:  http://oauth.example.com:8080/path
BAD:  http://example.org

循环重定向 URL

可选的 redirect_uri 参数也可以用于循环回送 URL,这对于运行在台式计算机上的原生应用程序很有用。如果应用程序指定了循环回送 URL 和端口,则在授权应用程序用户后,将被重定向到提供的 URL 和端口。redirect_uri 不需要与应用程序回调 URL 中指定的端口匹配。

对于 http://127.0.0.1/path 回调 URL,如果您的应用程序正在监听端口 1234,则可以使用此 redirect_uri

http://127.0.0.1:1234/path

请注意,OAuth RFC 建议不要使用 localhost,而是使用循环回送字面量 127.0.0.1 或 IPv6 ::1

为 OAuth 应用程序创建多个令牌

您可以为用户/应用程序/范围组合创建多个令牌,以创建用于特定用例的令牌。

如果您 OAuth 应用程序支持使用 GitHub 进行登录并仅需要基本用户信息的工作流程,这将很有用。另一个工作流程可能需要访问用户的私有仓库。使用多个令牌,您的 OAuth 应用程序可以为每个用例执行 Web 流程,仅请求所需的范围。如果用户仅使用您的应用程序登录,则他们永远不需要授予您的 OAuth 应用程序访问其私有仓库的权限。

每个用户/应用程序/范围组合最多可以发出十个令牌,每小时创建的令牌数量限制为十个。如果应用程序为同一用户和同一范围创建了超过十个令牌,则具有相同用户/应用程序/范围组合的最旧令牌将被撤销。但是,达到每小时速率限制不会撤销您最旧的令牌。相反,它将在浏览器中触发重新授权提示,要求用户再次检查他们授予您应用程序的权限。此提示旨在为应用程序可能陷入的任何潜在无限循环提供休息,因为应用程序在 1 小时内从用户那里请求十个令牌几乎没有理由。

警告:撤销 OAuth 应用程序的所有权限将删除应用程序代表用户生成的任何 SSH 密钥,包括 部署密钥

引导用户查看其访问权限

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

要构建此链接,您需要在注册应用程序时从 GitHub 收到的 OAuth 应用程序的 client_id

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

提示:要了解有关您的 OAuth 应用程序可以为用户访问的资源的更多信息,请参阅“发现用户的资源”。

故障排除

进一步阅读