关于用户访问令牌
注意:过期的用户访问令牌目前是一项可选功能,可能会有变动。 若要选择加入或退出令牌过期功能,请参阅“激活 GitHub 应用的可选功能”。 有关详细信息,请参阅“GitHub 应用的用户到服务器访问令牌过期”。
用户访问令牌是一种 OAuth 标记。 不同于传统 OAuth 标记,用户访问令牌不使用范围。 而是使用细粒度的权限。 用户访问令牌仅具有用户和应用都拥有的权限。 例如,如果向应用授予了写入存储库内容的权限,但用户只能读取内容,则用户访问令牌也只能读取内容。
同样,用户访问令牌只能访问用户和应用都可访问的资源。 例如,如果向应用授予了对存储库 A
和 B
的访问权限,并且用户可以访问存储库 B
和 C
,那么用户访问令牌可以访问存储库 B
,但不能访问 A
或 C
。 可以使用 REST API 检查用户访问令牌可以访问哪些安装以及安装中的哪些存储库。 有关详细信息,请参阅“GitHub 应用安装”中的 GET /user/installations
和 GET /user/installations/{installation_id}/repositories
。
使用用户访问令牌发出 API 请求时,用户访问令牌的速率限制适用。 有关详细信息,请参阅“GitHub 应用的速率限制”。
默认情况下,用户访问令牌在 8 小时后过期。 可以使用刷新令牌重新生成用户访问令牌。 有关详细信息,请参阅“刷新用户访问令牌”。
用户可以撤销其对 GitHub App 的授权。 有关详细信息,请参阅“令牌过期和吊销”。 如果用户撤销其对 GitHub App 的授权,应用会收到 github_app_authorization
Webhook。 GitHub Apps 无法取消订阅此事件。 如果应用收到此 Webhook,应停止代表已撤销令牌的用户调用 API。 如果应用继续使用已撤销的访问令牌,它将收到 401 Bad Credentials
错误。 有关此 Webhook 的详细信息,请参阅“Webhook 事件和有效负载”。
应确保用户访问令牌和刷新令牌的安全。 有关详细信息,请参阅“创建 GitHub 应用的最佳做法”。
注意:如果用户报告在授权 GitHub App 后看不到其组织拥有的资源,并且组织使用 SAML SSO,则指示用户在重新授权之前为其组织启动活动的 SAML 会话。 有关详细信息,请参阅 GitHub Enterprise Cloud 文档中的“SAML 和 GitHub 应用”。
使用 Web 应用程序流生成用户访问令牌
如果应用在浏览器中运行,应使用 Web 应用程序流来生成用户访问令牌。 有关使用 Web 应用流的教程,请参阅“使用 GitHub Apps 生成“使用 GitHub 登录”按钮”。
-
将用户定向到此 URL,并从以下参数列表添加任何必需的查询参数:
https://github.com/login/oauth/authorize
。 例如,此 URL 指定client_id
和state
参数:https://github.com/login/oauth/authorize?client_id=12345&state=abcdefg
。查询参数 类型 说明 client_id
string
必填。 GitHub App 的客户端 ID。 客户端 ID 不同于应用 ID。 可以在应用的设置页上找到客户端 ID。 若要详细了解如何导航到 GitHub App 的设置页,请参阅“修改 GitHub 应用注册”。 redirect_uri
string
用户获得授权后被发送到的应用程序中的 URL。 此 URL 必须与在应用设置中作为“回叫 URL”提供的 URL 之一完全匹配,并且不能包含任何附加参数。 state
string
指定后,该值应该包含一个随机字符串,以防止伪造攻击,并且可以包含任何其他任意数据。 login
string
指定后,Web 应用程序流会显示特定帐户,提示用户可使用该帐户登录和授权应用。 allow_signup
boolean
在 OAuth 流程中,是否向未经身份验证的用户提供注册 GitHub 的选项。 默认为 true
。 在策略禁止注册时使用false
。 -
如果用户接受授权请求,GitHub 会将用户重定向到应用设置中的回叫 URL 之一,并提供可用于在下一步中创建用户访问令牌的
code
查询参数。 如果在上一步中指定了redirect_uri
,则会使用该回叫 URL。 否则,将使用应用设置页上的第一个回叫 URL。如果在上一步中指定了
state
参数,GitHub 还将包含state
参数。 如果state
参数与在上一步中发送的state
参数不匹配,则无法信任请求,应中止 Web 应用程序流。 -
通过向此 URL 发出
POST
请求以及以下查询参数,将上一步中的code
换为用户访问令牌:https://github.com/login/oauth/access_token
查询参数 类型 说明 client_id
string
必填。 GitHub App 的客户端 ID。 客户端 ID 不同于应用 ID。 可以在应用的设置页上找到客户端 ID。 若要详细了解如何导航到 GitHub App 的设置页,请参阅“修改 GitHub 应用注册”。 client_secret
string
必填。 GitHub App的客户端密码。 可以在应用的设置页上生成客户端密码。 code
string
必填。 在上一步中收到的代码。 redirect_uri
string
用户获得授权后被发送到的应用程序中的 URL。 此 URL 必须与在设置 GitHub App 时作为“回叫 URL”提供的 URL 之一完全匹配,并且不能包含任何附加参数。 repository_id
string
用户访问令牌可以访问的单个存储库的 ID。 如果 GitHub App 或用户无法访问存储库,将忽略此项。 使用此参数可进一步限制用户访问令牌的访问权限。 -
GitHub 将做出包含以下参数的响应:
响应参数 类型 说明 access_token
string
用户访问令牌。 令牌以 ghu_
开头。expires_in
integer
access_token
过期前需经历的秒数。 如果禁用了用户访问令牌的有效期限,将省略此参数。 值将始终为28800
(8 小时)。refresh_token
string
刷新令牌。 如果禁用了用户访问令牌的有效期限,将省略此参数。 令牌以 ghr_
开头。refresh_token_expires_in
integer
refresh_token
过期前需经历的秒数。 如果禁用了用户访问令牌的有效期限,将省略此参数。 值将始终为15811200
(6 个月)。scope
string
令牌具有的范围。 此值将始终为空字符串。 不同于传统的 OAuth 标记,用户访问令牌仅限于应用和用户拥有的权限。 token_type
string
令牌类型。 值将始终为 bearer
。 -
使用上一步中的用户访问令牌代表用户发出 API 请求。 在 API 请求的
Authorization
标头中包含用户访问令牌。 例如:curl --request GET \ --url "https://api.github.com/user" \ --header "Accept: application/vnd.github+json" \ --header "Authorization: Bearer USER_ACCESS_TOKEN" \ --header "X-GitHub-Api-Version: 2022-11-28"
使用设备流生成用户访问令牌
注意:设备流处于公开测试阶段,可能会发生更改。
如果应用无外设应用或无权访问浏览器,应使用设备流来生成用户访问令牌。 例如,CLI 工具、简单的 Raspberry Pi 和桌面应用程序应使用设备流。 有关使用设备流的教程,请参阅“使用 GitHub Apps 生成 CLI”。
必须先在应用的设置中启用设备流,才能使用设备流。 有关启用设备流的详细信息,请参阅“修改 GitHub 应用注册”。
设备流使用 OAuth 2.0 设备授权模式。
-
向
https://github.com/login/device/code
发送POST
请求和client_id
查询参数。 客户端 ID 不同于应用 ID。 可以在应用的设置页上找到客户端 ID。 若要详细了解如何导航到 GitHub App 的设置页,请参阅“修改 GitHub 应用注册”。 -
GitHub 将做出包含以下查询参数的响应:
响应参数 类型 说明 device_code
string
用于验证设备的验证码。 该验证码长度为 40 个字符。 user_code
string
应用程序应该显示的验证码,以便用户可以在浏览器中输入该验证码。 此代码为 8 个字符,中间有连字符。 例如, WDJB-MJHT
。verification_uri
string
用户需要在其中输入其 user_code
的 URL。 该 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
) 以完成设备授权之前必须经过的最短秒数。 如果在经过此时间间隔前发出请求,则会达到速率限制并出现slow_down
错误。 默认值为 5 秒。 -
提示用户在
https://github.com/login/device
输入上一步中的user_code
。如果用户未在
expires_in
时间内输入该代码,该代码会失效。 在这种情况下,应重启设备流。 -
轮询
POST https://github.com/login/oauth/access_token
以及client_id
、device_code
和grant_type
查询参数(如下所述),直到设备和用户代码过期或用户通过输入user_code
成功授权应用。查询参数 类型 说明 client_id
string
必填。 GitHub App 的客户端 ID。 device_code
string
必填。 在上一步中收到的设备验证码。 grant_type
string
必填。 授权类型必须是 urn:ietf:params:oauth:grant-type:device_code
。repository_id
string
用户访问令牌可以访问的单个存储库的 ID。 如果 GitHub App 或用户无法访问存储库,将忽略此项。 使用此参数可进一步限制用户访问令牌的访问权限。 轮询此终结点的频率不要高于
interval
指示的频率。 如果这样做,会达到速率限制并出现slow_down
错误。slow_down
错误响应向上一个interval
添加 5 秒钟的时间。在用户输入代码之前,GitHub 将做出响应,其中包含一个 200 状态和一个
error
响应查询参数。错误名称 说明 authorization_pending
授权请求待处理并且用户尚未输入用户代码时,将发生此错误。 应用应持续轮询 POST https://github.com/login/oauth/access_token
,且轮询频率低于interval
指定的频率。slow_down
收到 slow_down
错误时,会使用POST https://github.com/login/oauth/access_token
向请求之间所需的最短interval
或时间范围添加 5 秒钟的额外时间。 例如,如果请求之间的启动间隔至少需要 5 秒,并且你收到了slow_down
错误响应,那么现在必须等待至少 10 秒,然后才能发出新的令牌请求。 错误响应包括必须使用的新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。 客户端 ID 不同于应用程序 ID 和客户端密码。 incorrect_device_code
提供的 device_code
无效。access_denied
当用户在授权过程中单击取消时,你将收到 access_denied
错误,该用户将无法再次使用验证码。device_flow_disabled
尚未在应用的设置中启用设备流。 有关启用设备流的详细信息,请参阅“修改 GitHub 应用注册”。 -
用户输入
user_code
后,GitHub 将做出包含以下查询参数的响应:响应参数 类型 说明 access_token
string
用户访问令牌。 令牌以 ghu_
开头。expires_in
integer
access_token
过期前需经历的秒数。 如果禁用了用户访问令牌的有效期限,将省略此参数。 值将始终为28800
(8 小时)。refresh_token
string
刷新令牌。 如果禁用了用户访问令牌的有效期限,将省略此参数。 令牌以 ghr_
开头。refresh_token_expires_in
integer
refresh_token
过期前需经历的秒数。 如果禁用了用户访问令牌的有效期限,将省略此参数。 值将始终为15811200
(6 个月)。scope
string
令牌具有的范围。 此值将始终为空字符串。 不同于传统的 OAuth 标记,用户访问令牌仅限于应用和用户拥有的权限。 token_type
string
令牌类型。 值将始终为 bearer
。 -
使用上一步中的用户访问令牌代表用户发出 API 请求。 在 API 请求的
Authorization
标头中包含用户访问令牌。 例如:curl --request GET \ --url "https://api.github.com/user" \ --header "Accept: application/vnd.github+json" \ --header "Authorization: Bearer USER_ACCESS_TOKEN" \ --header "X-GitHub-Api-Version: 2022-11-28"
在用户安装应用时生成用户访问令牌
如果在应用设置中选择“在安装过程中请求用户授权(OAuth)”,GitHub 会在用户安装应用后立即启动 Web 应用程序流。
无论应用是安装在用户帐户上还是组织帐户上,都可以使用此方法生成用户访问令牌。 但是,如果应用安装在组织帐户上,则需要使用 Web 应用程序流或设备流来为组织中的其他用户生成用户访问令牌。
-
当用户安装应用时,GitHub 会将用户重定向到
https://github.com/login/oauth/authorize?client_id=CLIENT_ID
,其中CLIENT_ID
是应用的客户端 ID。 -
如果用户接受你的授权请求,GitHub 会将用户重定向到应用设置中的第一个回叫 URL,并提供
code
查询参数。如果要控制使用的回叫 URL,请不要选择“在安装过程中请求用户授权(OAuth)”。 而是要引导用户完成整个 Web 应用程序流,并指定
redirect_uri
参数。 -
通过向此 URL 发出
POST
请求以及以下查询参数,将上一步中的code
换为用户访问令牌:https://github.com/login/oauth/access_token
查询参数 类型 说明 client_id
string
必填。 GitHub App 的客户端 ID。 客户端 ID 不同于应用 ID。 可以在应用的设置页上找到客户端 ID。 若要详细了解如何导航到 GitHub App 的设置页,请参阅“修改 GitHub 应用注册”。 client_secret
string
必填。 GitHub App的客户端密码。 可以在应用的设置页上生成客户端密码。 code
string
必填。 在上一步中收到的代码。 redirect_uri
string
用户获得授权后被发送到的应用程序中的 URL。 此 URL 必须与在设置 GitHub App 时作为“回叫 URL”提供的 URL 之一完全匹配,并且不能包含任何附加参数。 repository_id
string
用户访问令牌可以访问的单个存储库的 ID。 如果 GitHub App 或用户无法访问存储库,将忽略此项。 使用此参数可进一步限制用户访问令牌的访问权限。 -
GitHub 将做出包含以下参数的响应:
响应参数 类型 说明 access_token
string
用户访问令牌。 令牌以 ghu_
开头。expires_in
integer
access_token
过期前需经历的秒数。 如果禁用了用户访问令牌的有效期限,将省略此参数。 值将始终为28800
(8 小时)。refresh_token
string
刷新令牌。 如果禁用了用户访问令牌的有效期限,将省略此参数。 令牌以 ghr_
开头。refresh_token_expires_in
integer
refresh_token
过期前需经历的秒数。 如果禁用了用户访问令牌的有效期限,将省略此参数。 值将始终为15811200
(6 个月)。scope
string
令牌具有的范围。 此值将始终为空字符串。 不同于传统的 OAuth 标记,用户访问令牌仅限于应用和用户拥有的权限。 token_type
string
令牌类型。 值将始终为 bearer
。 -
使用上一步中的用户访问令牌代表用户发出 API 请求。 在 API 请求的
Authorization
标头中包含用户访问令牌。 例如:curl --request GET \ --url "https://api.github.com/user" \ --header "Accept: application/vnd.github+json" \ --header "Authorization: Bearer USER_ACCESS_TOKEN" \ --header "X-GitHub-Api-Version: 2022-11-28"
使用刷新令牌生成用户访问令牌
默认情况下,用户访问令牌在 8 小时后过期。 如果收到带有过期时间的用户访问令牌,则会同时收到刷新令牌。 刷新令牌在 6 个月后过期。 可以使用此刷新令牌重新生成用户访问令牌。 有关详细信息,请参阅“刷新用户访问令牌”。
GitHub 强烈建议使用会过期的用户访问令牌。 如果之前选择不使用会过期的用户访问令牌,但希望重新启用此功能,请参阅“激活 GitHub 应用的可选功能”。
疑难解答
以下部分概述了生成用户访问令牌时可能收到的一些错误。
客户端凭据不正确
如果指定的 client_id
或 client_secret
不正确,将收到 incorrect_client_credentials
错误。
若要解决此错误,请确保对 GitHub App 使用正确的凭据。 可以在 GitHub App 的设置页面上找到客户端 ID 和客户端密码。 若要详细了解如何导航到 GitHub App 设置页面,请参阅“修改 GitHub 应用注册”。
重定向 URI 不匹配
如果指定的 redirect_uri
与 GitHub App 注册中的其中一个回调 URL 不匹配,将收到 redirect_uri_mismatch
错误。
若要解决此错误,请提供与 GitHub App 注册的其中一个回调 URL 匹配的 redirect_uri
,或省略此参数以默认为 GitHub App 注册中列出的第一个回调 URL。 有关详细信息,请参阅“关于用户授权回调 URL”。
验证码错误
如果使用设备流,并且你指定的验证码 (device_code
) 不正确、已过期或与从对 https://github.com/login/device/code
的初始请求收到的值不匹配,你将收到 bad_verification_code
错误。
若要解决此错误,应再次启动设备流以获取新代码。 有关详细信息,请参阅“使用设备流生成用户访问令牌”。
不好的刷新令牌
如果你指定的刷新令牌无效或已过期,你将收到 bad_refresh_token
错误。
若要解决此错误,必须重启 Web 应用程序流或设备流,以获取新的用户访问令牌和刷新令牌。 仅当 GitHub App 已选择使用即将过期的用户访问令牌时,你才会收到刷新令牌。 有关详细信息,请参阅“刷新用户访问令牌”。
不支持的授权类型
通过设备流请求用户访问令牌时,grant_type
参数必须为 urn:ietf:params:oauth:grant-type:device_code
。 使用刷新令牌请求用户访问令牌时,grant_type
参数必须为 refresh_token
。 如果不使用正确的授权类型,你将收到 unsupported_grant_type
错误。
未经验证的用户电子邮件
如果你尝试为其生成用户访问令牌的用户尚未向 GitHub 验证其主要电子邮件地址,你将收到 unverified_user_email
错误。
若要解决此错误,请提示用户验证在 GitHub 帐户上验证其主要电子邮件地址。 有关详细信息,请参阅 “验证电子邮件地址”。