Note
请考虑生成 GitHub App 而不是 OAuth app。
OAuth apps 和 GitHub Apps 使用 OAuth 2.0。
GitHub Apps 可以代表用户执行操作(类似于 OAuth app),也可以自行执行操作,这对不需要用户输入的自动程序很有利。 此外,GitHub Apps 使用细化权限,让用户更好地控制应用可以访问的存储库,并使用生存期较短的令牌。 有关详细信息,请参阅“GitHub 应用和 OAuth 应用之间的差异”和“关于创建 GitHub 应用”。
GitHub Enterprise Cloud 的 OAuth 实现支持标准授权代码授权类型和对无权访问 Web 浏览器的应用的 OAuth 2.0 设备授权。
如果想跳过以标准方式授权应用(例如在测试应用时),可以使用非 Web 应用程序流。
要授权你的 OAuth app,请考虑哪个授权流程最适合你的应用。
Note
本文包含使用 github.com
域的命令或示例。 可以在其他域(例如 octocorp.ghe.com
)中访问 GitHub。
Web 应用程序流程
Note
如果要生成 GitHub 应用,仍可以使用 OAuth Web 应用程序流,但设置方面有一些重要差别。 有关详细信息,请参阅“代表用户使用 GitHub 应用进行身份验证”。
授权应用程序用户的 web 应用程序流程是:
- 用户被重定向,以请求他们的 GitHub 身份
- 用户被 GitHub 重定向回您的站点
- 您的应用程序使用用户的访问令牌访问 API
1. 请求用户的 GitHub 标识
GET https://github.com/login/oauth/authorize
此终结点采用以下输入参数。
查询参数 | 类型 | 必需? | 说明 |
---|---|---|---|
client_id | string | 必须 | 注册时从 GitHub 收到的客户端 ID。 |
redirect_uri | string | 强烈建议 | 用户获得授权后被发送到的应用程序中的 URL。 请参阅以下有关重定向 URL 的详细信息。 |
login | string | 可选 | 提供用于登录和授权应用程序的特定账户。 |
scope | string | 上下文相关 | 范围的空格分隔列表。 如果未提供,则 scope 默认为未授权应用程序的任何范围的用户的空列表。 对于已向应用程序授权作用域的用户,不会显示含作用域列表的 OAuth 授权页面。 相反,通过用户向应用程序授权的作用域集,此流程步骤将自动完成。 例如,如果用户已经执行了两次 Web 流,并且已授权一个具有 user 范围的令牌和另一个具有 repo 范围的令牌,则不提供 scope 的第三个 Web 流将收到具有 user 和 repo 范围的令牌。 |
state | string | 强烈建议 | 不可猜测的随机字符串。 它用于防止跨站请求伪造攻击。 |
allow_signup | string | 可选 | 在 OAuth 流程中,是否向经过验证的用户提供注册 GitHub 的选项。 默认为 true 。 在策略禁止注册时使用 false 。 |
prompt | string | 可选 | 强制帐户选取器在设置为 select_account 时显示。 如果应用程序具有非 HTTP 重定向 URI,或者用户登录了多个帐户,则帐户选取器也会显示。 |
PKCE(用于代码交换的证明密钥)参数 code_challenge
和 code_challenge_method
目前不受支持。 目前不支持 CORS 预检请求 (OPTIONS)。
2. 用户被 GitHub 重定向回你的站点
如果用户接受你的请求,GitHub Enterprise Cloud 会使用代码参数中的临时 code
以及你在上一步的 state
参数中提供的状态重定向回你的站点。 临时代码将在 10 分钟后到期。 如果状态不匹配,然后第三方创建了请求,您应该中止此过程。
将此 code
交换为访问令牌:
POST https://github.com/login/oauth/access_token
此终结点采用以下输入参数。
参数名称 | 类型 | 必需? | 说明 |
---|---|---|---|
client_id | string | 必须 | 从 GitHub Enterprise Cloud 收到的 OAuth app 的客户端 ID。 |
client_secret | string | 必须 | 从 GitHub Enterprise Cloud 收到的 OAuth app 的客户端密码。 |
code | string | 必须 | 收到的作为对步骤 1 的响应的代码。 |
redirect_uri | string | 强烈建议 | 用户获得授权后被发送到的应用程序中的 URL。 我们可以使用此参数来匹配发放 code 时最初提供的 URI,以防止对服务的攻击。 |
默认情况下,响应采用以下形式:
access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a&scope=repo%2Cgist&token_type=bearer
如果在 Accept
标头中提供格式,则还可以接收不同格式的响应。 例如 Accept: application/json
或 Accept: 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 中设置“授权”标头:
curl -H "Authorization: Bearer OAUTH-TOKEN" https://api.github.com/user
每次收到访问令牌时,都应使用该令牌重新验证用户的标识。 当你向他们发送邮件授权应用时,用户可以更改他们登录的帐户,如果在每次登录后没有验证用户的标识,则可能会出现混合用户数据的风险。
设备流程
设备流允许你授权用户使用无头应用程序,例如 CLI 工具或 Git 凭据管理器。
在使用设备流识别和授权用户之前,必须先在应用的设置中启用它。 有关在应用中启用设备流的详细信息,请参阅“修改 GitHub 应用注册”(对于 GitHub Apps)和“修改 OAuth 应用”(对于 OAuth apps)。
设备流程概述
- 您的应用程序会请求设备和用户验证码,并获取用户将在其中输入用户验证码的授权 URL。
- 应用程序提示用户在
https://github.com/login/device
中输入用户验证码。 - 应用程序轮询用户身份验证状态。 用户授权设备后,应用程序将能够使用新的访问令牌进行 API 调用。
第 1 步:应用程序从 GitHub 请求设备和用户验证码
POST https://github.com/login/device/code
您的应用程序必须请求用户验证码和验证 URL,因为应用程序在下一步中提示用户进行身份验证时将使用它们。 此请求还返回设备验证代码,应用程序必须使用它们来接收访问令牌和检查用户身份验证的状态。
终结点采用以下输入参数。
参数名称 | 类型 | 说明 |
---|---|---|
client_id | string | 必填。 从 GitHub Enterprise Cloud 收到的应用的客户端 ID。 |
scope | string | 应用请求访问的范围的列表(以空格分隔)。 有关详细信息,请参阅“OAuth 应用的范围”。 |
默认情况下,响应采用以下形式:
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 。 |
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
:
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 | string | 必填。 从 GitHub Enterprise Cloud 收到的 OAuth app 的客户端 ID。 |
device_code | string | **** 必需。 你从 POST https://github.com/login/device/code 请求中收到的 device_code 。 |
grant_type | string | **** 必需。 授权类型必须是 urn:ietf:params:oauth:grant-type:device_code 。 |
默认情况下,响应采用以下形式:
access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a&token_type=bearer&scope=repo%2Cgist
如果在 Accept
标头中提供格式,则还可以接收不同格式的响应。 例如 Accept: application/json
或 Accept: 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 秒钟的时间。 有关详细信息,请参阅设备流代码错误。
设备流程的错误代码
错误代码 | 说明 |
---|---|
authorization_pending | 授权请求待处理并且用户尚未输入用户代码时,将发生此错误。 应用应在不超出 interval 的情况下继续轮询 POST https://github.com/login/oauth/access_token 请求,这需要每个请求之间的最短秒数。 |
slow_down | 收到 slow_down 错误时,会使用 POST https://github.com/login/oauth/access_token 向请求之间所需的最短 interval 或时间范围添加 5 秒钟的额外时间。 例如,如果请求之间的启动间隔至少需要 5 秒,并且你收到了 slow_down 错误响应,那么现在必须等待至少 10 秒,然后才能发出新的 OAuth 访问令牌请求。 错误响应包括必须使用的新 interval 。 |
expired_token | 如果设备代码已过期,则将看到 token_expired 错误。 您必须发出新的设备代码请求。 |
unsupported_grant_type | 轮询 OAuth 令牌请求 POST https://github.com/login/oauth/access_token 时,授权类型必须为 urn:ietf:params:oauth:grant-type:device_code 并且必须作为输入参数包含在内。 |
incorrect_client_credentials | 对于设备流程,您必须传递应用程序的客户端 ID,您可以在应用程序设置页面上找到该 ID。 设备流不需要 client_secret 。 |
incorrect_device_code | 提供的 device_code 无效。 |
access_denied | 当用户在授权过程中单击取消时,你将收到 access_denied 错误,该用户将无法再次使用验证码。 |
device_flow_disabled | 尚未在应用的设置中启用设备流。 有关详细信息,请参阅“设备流”。 |
有关详细信息,请参阅“OAuth 2.0 设备授权”。
非 Web 应用程序流程
非 web 身份验证适用于测试等有限的情况。 如果需要,可以使用基本身份验证通过 personal access token 设置页创建 personal access token。 此方法支持用户随时撤销访问权限。
重定向 URL
redirect_uri
参数是可选的。 如果忽略该参数,GitHub 会将用户重定向到 OAuth app 设置中配置的回叫 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 apps 创建多个令牌
您可以为用户/应用程序/作用域组合创建多个令牌,以便为特定用例创建令牌。
如果你的 OAuth app 支持一个使用 GitHub 登录且只需基本用户信息的工作流程,此方法将非常有用。 另一个工作流程可能需要访问用户的私有仓库。 你的 OAuth app 可以使用多个令牌为每个用例执行 Web 流程,只需要所需的作用域。 如果用户仅使用你的应用程序登录,则无需向他们的专用存储库授予你的 OAuth app 访问权限。
每个用户/应用程序/作用域组合签发的令牌数量有限,速率限制是每小时创建十个令牌。 如果应用程序为同一用户和相同作用域创建超过十个令牌,则将撤销具有相同用户/应用程序/作用域组合的最旧令牌。 但是,达到每小时速率限制不会撤销最早的令牌。 相反,它会在浏览器中触发重新授权提示,要求用户仔细检查他们向你的应用授予的权限。 此提示旨在中断应用陷入的任何潜在的无限循环,因为应用几乎没有理由在一小时内向用户请求十个令牌。
警告:从 OAuth app 撤销所有权限将会删除应用程序代表用户生成的所有 SSH 密钥,包括部署密钥。
指示用户审查其访问权限
可以链接至 OAuth app 的授权信息,以便用户审查和撤销其应用程序授权。
若要生成此链接,需要使用在注册应用程序时从 GitHub 收到的 OAuth app 的 client_id
。
https://github.com/settings/connections/applications/:client_id
Tip
若要详细了解 OAuth app 可以为用户访问的资源,请参阅“为用户发现资源”。
故障排除
- “排查授权请求错误”
- “排查 OAuth 应用访问令牌请求错误”
- “设备流错误”
- “令牌过期和吊销”