注意
请考虑构建GitHub App,而不是OAuth app。
OAuth apps 和 GitHub Apps 均使用 OAuth 2.0。
GitHub Apps 可以代表用户(类似于 OAuth app或自己)执行操作,这对于不需要用户输入的自动化有利。 此外, GitHub Apps 使用细粒度的权限,让用户可以更好地控制应用可以访问的存储库,并使用生存期较短的令牌。 有关详细信息,请参阅 GitHub 应用和 OAuth 应用之间的差异 和 关于创建GitHub应用。
GitHub 的 OAuth 实现支持标准的 授权码授权类型 以及适用于无法访问 Web 浏览器的应用的 OAuth 2.0 设备授权授予。
如果想跳过以标准方式授权应用(例如在测试应用时),可以使用非 Web 应用程序流。
要为您的 OAuth app 授权,请考虑哪种授权流程最适合您的应用。
即将过期的访问令牌
若要强制定期轮换令牌并减少已泄露令牌的影响,可以将你的 OAuth app 配置为获取会过期的访问令牌。 当应用使用过期的访问令牌时,你还将收到包含访问令牌的刷新令牌。 Web 应用程序流和设备流都支持过期令牌。
访问令牌会在 8 小时后过期,而刷新令牌会在连续 6 个月未使用后过期。 可以使用刷新令牌生成新的访问令牌和新的刷新令牌。 有关详细信息,请参阅 使用刷新令牌刷新访问令牌。
在运行时选择启用会过期的令牌
若要测试并逐步推出对将要过期的令牌的支持,您可以请求 offline_access 范围以及你的其他范围来选择接收将要过期令牌和刷新令牌以用于单次登录。 请求 offline_access 范围时,即使应用未配置为使用过期令牌,也会收到即将过期的访问令牌和刷新令牌。
如果您的应用同时支持 GitHub Enterprise Server 和 offline_access,则应做好 GitHub.com 作用域可能不起作用的准备,因为 GitHub Enterprise Server 实例可能尚不支持过期令牌。 在这种情况下,你将收到一个未过期的令牌,并且不会收到刷新令牌,因此你的应用不应假定始终返回刷新令牌。
要求你的应用使用有时效的令牌
更新应用以使用刷新令牌来处理令牌过期后,可以全局强制应用令牌过期。 这将导致所有新令牌在签发时都带有过期时间和刷新令牌。 启用此功能不会导致现有令牌过期 , 它们将继续生存期较长。 如果要切换到即将过期的令牌,请让用户再次登录。 若要为应用配置此设置,请参阅 激活 OAuth 应用的可选功能。
Web 应用程序流程
注意
如果要生成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 范围的令牌。 |
使用 offline_access作用域来获取会过期的令牌,不会改变该作用域的行为——系统不会像跟踪 repo 或 user 这类常规作用域那样跟踪它,因此使用它时也不会触发额外的提示。 | |||
state | string | 强烈建议 | 不可猜测的随机字符串。 它用于防止跨站请求伪造攻击。 |
code_challenge | string | 强烈建议 | 用于使用 PKCE(代码交换的证明密钥)保护身份验证流。 如果包含 code_challenge_,则需要。 必须是客户端生成的随机字符串,包含 43 个字符且为 SHA-256 哈希值。 有关此安全扩展的更多详细信息,请参阅 PKCE RFC。 |
code_challenge_ | 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 中,也可以在身份验证期间存储在会话变量中,具体取决于应用程序体系结构。 |
默认情况下,响应采用以下形式:
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>
如果你的 OAuth app 使用会过期的访问令牌,或者你请求了 offline_access 范围,则响应还会包含一个 refresh_token,以及 expires_in 和 refresh_token_expires_in 值,用于指示每个令牌何时过期(以从当前时刻起的秒数表示)。 有关详细信息,请参阅 “即将过期的访问令牌”。
默认情况下,响应采用以下形式:
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 中设置“授权”标头:
curl -H "Authorization: Bearer OAUTH-TOKEN" https://api.github.com/user
每次收到访问令牌时,都应使用该令牌重新验证用户的标识。 当你向他们发送邮件授权应用时,用户可以更改他们登录的帐户,如果在每次登录后没有验证用户的标识,则可能会出现混合用户数据的风险。
设备流动
设备流允许你授权用户使用无头应用程序,例如 CLI 工具或 Git 凭据管理器。
在使用设备流识别和授权用户之前,必须先在应用的设置中启用它。 有关在应用中启用设备流的详细信息,请参阅针对 的 GitHub Apps 以及针对 的 OAuth apps。
设备流程概述
- 您的应用程序会请求设备和用户验证码,并获取用户将在其中输入用户验证码的授权 URL。
- 应用提示用户输入用户验证码
https://github.com/login/device。 - 应用程序轮询用户的身份验证状态。 用户授权设备后,应用程序将能够使用新的访问令牌进行 API 调用。
步骤 1:应用从GitHub请求设备和用户验证码
POST https://github.com/login/device/code
您的应用程序必须请求用户验证码和验证 URL,因为应用程序在下一步中提示用户进行身份验证时将使用它们。 此请求还返回设备验证代码,应用程序必须使用它们来接收访问令牌和检查用户身份验证的状态。
终结点采用以下输入参数。
| 参数名称 | 类型 | 说明 |
|---|---|---|
client_id | string | |
| 必填。 从 GitHub 中针对应用接收的客户端 ID。 |