跳至主要内容

为 GitHub 应用生成用户访问令牌

您可以生成 GitHub 应用的用户访问令牌,以便将应用活动归因于用户。

关于用户访问令牌

注意

用户访问令牌过期目前是一项可选功能,如有更改,恕不另行通知。要启用或禁用令牌过期功能,请参阅“激活 GitHub 应用的可选功能”。更多信息,请参阅“GitHub 应用的用户到服务器访问令牌过期”。

如果用户报告授权您的 GitHub 应用后无法查看其组织拥有的资源,并且该组织使用 SAML SSO,请指示用户在其组织中启动一个活动的 SAML 会话,然后再重新授权。更多信息,请参阅 GitHub Enterprise Cloud 文档中的“SAML 和 GitHub 应用”。

用户访问令牌是一种 OAuth 令牌。与传统的 OAuth 令牌不同,用户访问令牌不使用作用域。而是使用细粒度的权限。用户访问令牌仅具有用户和应用都拥有的权限。例如,如果应用被授予写入存储库内容的权限,但用户只能读取内容,则用户访问令牌只能读取内容。

同样,用户访问令牌只能访问用户和应用都可以访问的资源。例如,如果应用被授予访问存储库AB的权限,而用户可以访问存储库BC,则用户访问令牌可以访问存储库B,但不能访问AC。您可以使用 REST API 检查用户访问令牌可以访问哪些安装和安装中的哪些存储库。更多信息,请参阅“GitHub 应用安装的 REST API 端点”中的GET /user/installationsGET /user/installations/{installation_id}/repositories

使用用户访问令牌发出 API 请求时,将应用用户访问令牌的速率限制。更多信息,请参阅“GitHub 应用的速率限制”。

默认情况下,用户访问令牌在 8 小时后过期。您可以使用刷新令牌重新生成用户访问令牌。更多信息,请参阅“刷新用户访问令牌”。

用户可以撤销其对 GitHub 应用的授权。更多信息,请参阅“令牌过期和撤销”。如果用户撤销其对 GitHub 应用的授权,则应用将收到github_app_authorization Webhook。GitHub 应用无法取消订阅此事件。如果您的应用收到此 Webhook,则应停止代表撤销令牌的用户调用 API。如果您的应用继续使用已撤销的访问令牌,它将收到401 Bad Credentials错误。有关此 Webhook 的更多信息,请参阅“Webhook 事件和有效负载”。

您应妥善保管用户访问令牌和刷新令牌。更多信息,请参阅“创建 GitHub 应用的最佳实践”。

使用 Web 应用流程生成用户访问令牌

如果您的应用在浏览器中运行,则应使用 Web 应用流程生成用户访问令牌。有关使用 Web 应用流程的教程,请参阅“使用 GitHub 应用构建“使用 GitHub 登录”按钮”。

  1. 将用户定向到此 URL,并添加以下参数列表中的任何必要的查询参数:https://github.com/login/oauth/authorize。例如,此 URL 指定client_idstate参数:https://github.com/login/oauth/authorize?client_id=12345&state=abcdefg

    查询参数类型必需?描述
    client_id字符串必需您的 GitHub 应用的客户端 ID。客户端 ID 与应用 ID 不同。您可以在应用的设置页面上找到客户端 ID。有关导航到 GitHub 应用设置页面的更多信息,请参阅“修改 GitHub 应用注册”。
    redirect_uri字符串强烈建议授权后将用户发送到的应用程序中的 URL。这必须与您在应用设置中提供的“回调 URL”之一完全匹配,并且不能包含任何其他参数。
    state字符串强烈建议如果指定,则该值应包含一个随机字符串以防止伪造攻击,并且还可以包含任何其他任意数据。
    login字符串可选如果指定,则 Web 应用流程将提示用户使用特定帐户登录并授权您的应用。
    allow_signup布尔值可选未经身份验证的用户是否会在 OAuth 流程中获得注册 GitHub 的选项。默认为true。当策略禁止注册时,使用false
    prompt字符串可选如果设置为select_account,则强制出现帐户选择器。如果应用程序具有非 HTTP 重定向 URI 或用户已登录多个帐户,则也会出现帐户选择器。
  2. 如果用户接受您的授权请求,GitHub 将会将用户重定向到应用设置中的一个回调 URL,并提供一个code查询参数,您可以在下一步中使用它来创建用户访问令牌。如果您在上一步中指定了redirect_uri,则将使用该回调 URL。否则,将使用应用设置页面上的第一个回调 URL。

    如果您在上一步中指定了state参数,GitHub 还将包含state参数。如果state参数与您在上一步中发送的state参数不匹配,则无法信任该请求,应中止 Web 应用流程。

  3. 通过向此 URL 发出POST请求以及以下查询参数,将上一步中的code交换为用户访问令牌:https://github.com/login/oauth/access_token

    查询参数类型描述
    client_id字符串**必需。**您的 GitHub 应用的客户端 ID。客户端 ID 与应用 ID 不同。您可以在应用的设置页面上找到客户端 ID。有关导航到 GitHub 应用设置页面的更多信息,请参阅“修改 GitHub 应用注册”。
    client_secret字符串**必需。**您的 GitHub 应用的客户端密钥。您可以在应用的设置页面上生成客户端密钥。
    code字符串**必需。**您在上一步中收到的代码。
    redirect_uri字符串授权后将用户发送到的应用程序中的 URL。这必须与您在设置 GitHub 应用时提供的“回调 URL”之一完全匹配,并且不能包含任何其他参数。
    repository_id字符串用户访问令牌可以访问的单个存储库的 ID。如果 GitHub 应用或用户无法访问该存储库,则将忽略此项。使用此参数可以进一步限制用户访问令牌的访问权限。
  4. GitHub 将给出包含以下参数的响应

    响应参数类型描述
    access_token字符串用户访问令牌。令牌以ghu_开头。
    expires_in整数access_token过期前的秒数。如果您禁用了用户访问令牌的过期,则会省略此参数。该值将始终为28800(8 小时)。
    refresh_token字符串刷新令牌。如果您禁用了用户访问令牌的过期,则会省略此参数。令牌以ghr_开头。
    refresh_token_expires_in整数refresh_token过期前的秒数。如果您禁用了用户访问令牌的过期,则会省略此参数。该值将始终为15897600(6 个月)。
    scope字符串令牌具有的作用域。此值将始终为空字符串。与传统的 OAuth 令牌不同,用户访问令牌仅限于您的应用和用户都拥有的权限。
    token_type字符串令牌的类型。该值将始终为bearer
  5. 使用上一步中的用户访问令牌代表用户发出 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 应用构建 CLI”。

在使用设备流程之前,您必须先在应用设置中启用它。有关启用设备流程的更多信息,请参阅“修改 GitHub 应用注册”。

设备流程使用 OAuth 2.0 设备授权授权。

  1. https://github.com/login/device/code发送POST请求以及client_id查询参数。客户端 ID 与应用 ID 不同。您可以在应用的设置页面上找到客户端 ID。有关导航到 GitHub 应用设置页面的更多信息,请参阅“修改 GitHub 应用注册”。

  2. GitHub 将给出包含以下查询参数的响应

    响应参数类型描述
    device_code字符串用于验证设备的验证码。此代码为 40 个字符长。
    user_code字符串一个您的应用程序应该显示的验证码,以便用户可以在浏览器中输入该代码。此代码包含 8 个字符,中间带有一个连字符。例如,WDJB-MJHT
    verification_uri字符串用户需要输入其user_code 的网址。网址为:https://github.com/login/device
    expires_in整数device_codeuser_code 过期前的时间(秒)。默认值为 900 秒(15 分钟)。
    interval整数您可以发出新的访问令牌请求 (POST https://github.com/login/oauth/access_token) 以完成设备授权之前必须经过的最少秒数。如果您在此间隔时间之前发出请求,则会遇到速率限制并收到 slow_down 错误。默认值为 5 秒。
  3. 提示用户在 https://github.com/login/device 输入上一步中的 user_code

    如果用户在 expires_in 时间过去之前没有输入代码,则该代码将无效。在这种情况下,您应该重新启动设备流程。

  4. 轮询 POST https://github.com/login/oauth/access_token 以及 client_iddevice_codegrant_type 查询参数(如下所述),直到设备和用户代码过期或用户通过输入 user_code 成功授权应用程序。

    查询参数类型描述
    client_id字符串必填。您的 GitHub 应用程序的客户端 ID。
    device_code字符串必填。您在上一步中收到的设备验证码。
    grant_type字符串必填。授权类型必须为 urn:ietf:params:oauth:grant-type:device_code
    repository_id字符串用户访问令牌可以访问的单个存储库的 ID。如果 GitHub 应用或用户无法访问该存储库,则将忽略此项。使用此参数可以进一步限制用户访问令牌的访问权限。

    不要以高于 interval 指示的频率轮询此端点。如果您这样做,则会遇到速率限制并收到 slow_down 错误。slow_down 错误响应会将 5 秒添加到上次的 interval

    在用户输入代码之前,GitHub 将返回 200 状态和一个 error 响应查询参数。

    错误名称描述
    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 秒才能发出新的令牌请求。错误响应包含您必须使用的新的 interval
    expired_token如果设备代码过期,则您将看到 token_expired 错误。您必须发出新的设备代码请求。
    unsupported_grant_type授权类型必须为 urn:ietf:params:oauth:grant-type:device_code,并在您轮询 OAuth 令牌请求 POST https://github.com/login/oauth/access_token 时将其作为输入参数包含在内。
    incorrect_client_credentials对于设备流程,您必须传递应用程序的客户端 ID,您可以在应用程序设置页面上找到它。客户端 ID 与应用程序 ID 和客户端密钥不同。
    incorrect_device_code提供的 device_code 无效。
    access_denied当用户在授权过程中单击取消时,您将收到 access_denied 错误,并且用户将无法再次使用验证码。
    device_flow_disabled在应用程序设置中尚未启用设备流程。有关启用设备流程的更多信息,请参阅“修改 GitHub 应用程序注册”。
  5. 用户输入 user_code 后,GitHub 将提供包含以下查询参数的响应

    响应参数类型描述
    access_token字符串用户访问令牌。令牌以ghu_开头。
    expires_in整数access_token过期前的秒数。如果您禁用了用户访问令牌的过期,则会省略此参数。该值将始终为28800(8 小时)。
    refresh_token字符串刷新令牌。如果您禁用了用户访问令牌的过期,则会省略此参数。令牌以ghr_开头。
    refresh_token_expires_in整数refresh_token过期前的秒数。如果您禁用了用户访问令牌的过期,则会省略此参数。该值将始终为15897600(6 个月)。
    scope字符串令牌具有的作用域。此值将始终为空字符串。与传统的 OAuth 令牌不同,用户访问令牌仅限于您的应用和用户都拥有的权限。
    token_type字符串令牌的类型。该值将始终为bearer
  6. 使用上一步中的用户访问令牌代表用户发出 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 应用程序流程或设备流程为组织中的其他用户生成用户访问令牌。

  1. 用户安装您的应用程序时,GitHub 将将用户重定向到 https://github.com/login/oauth/authorize?client_id=CLIENT_ID,其中 CLIENT_ID 是您的应用程序的客户端 ID。

  2. 如果用户接受您的授权请求,GitHub 将将用户重定向到应用程序设置中的第一个回调 URL,并提供 code 查询参数。

    如果您想控制使用的回调 URL,请不要选择在安装期间请求用户授权 (OAuth)。而是通过完整的 Web 应用程序流程引导用户,并指定 redirect_uri 参数。

  3. 通过向此 URL 发出POST请求以及以下查询参数,将上一步中的code交换为用户访问令牌:https://github.com/login/oauth/access_token

    查询参数类型描述
    client_id字符串**必需。**您的 GitHub 应用的客户端 ID。客户端 ID 与应用 ID 不同。您可以在应用的设置页面上找到客户端 ID。有关导航到 GitHub 应用设置页面的更多信息,请参阅“修改 GitHub 应用注册”。
    client_secret字符串**必需。**您的 GitHub 应用的客户端密钥。您可以在应用的设置页面上生成客户端密钥。
    code字符串**必需。**您在上一步中收到的代码。
    redirect_uri字符串授权后将用户发送到的应用程序中的 URL。这必须与您在设置 GitHub 应用时提供的“回调 URL”之一完全匹配,并且不能包含任何其他参数。
    repository_id字符串用户访问令牌可以访问的单个存储库的 ID。如果 GitHub 应用或用户无法访问该存储库,则将忽略此项。使用此参数可以进一步限制用户访问令牌的访问权限。
  4. GitHub 将给出包含以下参数的响应

    响应参数类型描述
    access_token字符串用户访问令牌。令牌以ghu_开头。
    expires_in整数access_token过期前的秒数。如果您禁用了用户访问令牌的过期,则会省略此参数。该值将始终为28800(8 小时)。
    refresh_token字符串刷新令牌。如果您禁用了用户访问令牌的过期,则会省略此参数。令牌以ghr_开头。
    refresh_token_expires_in整数refresh_token过期前的秒数。如果您禁用了用户访问令牌的过期,则会省略此参数。该值将始终为15897600(6 个月)。
    scope字符串令牌具有的作用域。此值将始终为空字符串。与传统的 OAuth 令牌不同,用户访问令牌仅限于您的应用和用户都拥有的权限。
    token_type字符串令牌的类型。该值将始终为bearer
  5. 使用上一步中的用户访问令牌代表用户发出 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_idclient_secret 不正确,您将收到 incorrect_client_credentials 错误。

要解决此错误,请确保使用 GitHub 应用程序的正确凭据。您可以在 GitHub 应用程序的设置页面上找到客户端 ID 和客户端密钥。有关导航到 GitHub 应用程序设置页面的更多信息,请参阅“修改 GitHub 应用程序注册”。

重定向 URI 不匹配

如果您指定的 redirect_uri 与 GitHub 应用程序注册中的任何回调 URL 不匹配,您将收到 redirect_uri_mismatch 错误。

要解决此错误,请提供与 GitHub 应用程序注册的回调 URL 之一匹配的 redirect_uri,或者省略此参数以默认为 GitHub 应用程序注册中列出的第一个回调 URL。有关更多信息,请参阅“关于用户授权回调 URL”。

验证码无效

如果您使用的是设备流程,并且您指定的验证码 (device_code) 不正确、过期或与您从对 https://github.com/login/device/code 的初始请求中收到的值不匹配,您将收到 bad_verification_code 错误。

要解决此错误,您应该重新启动设备流程以获取新的代码。有关更多信息,请参阅“使用设备流程生成用户访问令牌”。

刷新令牌无效

如果您指定的刷新令牌无效或过期,您将收到 bad_refresh_token 错误。

要解决此错误,您必须重新启动 Web 应用程序流程或设备流程以获取新的用户访问令牌和刷新令牌。只有在您的 GitHub 应用程序已选择使用过期的用户访问令牌时,您才会收到刷新令牌。有关更多信息,请参阅“刷新用户访问令牌”。

授权类型不受支持

通过设备流程请求用户访问令牌时,grant_type 参数必须为 urn:ietf:params:oauth:grant-type:device_code。当您使用刷新令牌刷新用户访问令牌时,grant_type 参数必须为 refresh_token。如果您不使用正确的授权类型,您将收到 unsupported_grant_type 错误。

未验证的用户邮箱

如果您尝试为尚未使用 GitHub 验证其主要电子邮件地址的用户生成用户访问令牌,您将收到 unverified_user_email 错误。

要解决此错误,请提示用户在其 GitHub 帐户上验证主要电子邮件地址。有关更多信息,请参阅“验证您的电子邮件地址”。