如何获取 GitHub 应用程序安装令牌来验证克隆存储库

问题描述 投票:0回答:1

我正在编写一个Python应用程序,需要从组织克隆私有存储库。我已经注册了一个 GitHub 应用程序,我可以在文档中看到这需要一个安装访问令牌,但是如何获取其中一个令牌的每个步骤都让我陷入了一个兔子洞(循环引用)链接。

python authentication github access-token github-api
1个回答
0
投票

为此需要几个步骤:首先,您需要手动从 GitHub 获取一些信息,然后您的应用程序需要执行一些操作,将其身份验证密钥交换为可用于身份验证的临时代码一个

git clone

收集信息

在编写函数来执行此操作之前,您需要三条信息,所有这些信息都可以从应用程序的设置中获取。到达那里

  1. 转到您为其创建应用程序的组织
  2. 前往
    Settings > Developer Settings > GitHub Apps
  3. 单击您正在使用的应用程序名称旁边的
    Edit
    ,然后使用 2FA 进行身份验证

您需要的三项信息是:

应用程序ID

此内容位于

General
页面顶部的
About
部分。

安装ID

如果您还没有安装该应用程序,您还需要将应用程序安装到组织中。完成此操作后,返回应用程序设置中的

Install App
页面,然后复制安装设置的链接。将其粘贴到编辑器中并从末尾获取数字。链接的格式应为
https://github.com/apps/{app_name}/installations/{installation_id}
;最后一个
/
之后的部分是安装ID。

(如果您安装了多个应用程序,可能有一种方法可以通过编程方式获取此内容;我没有研究过这一点,因为我的用例不需要它。)

PEM 文件

这就是您向 GitHub 证明您控制该应用程序的方式。返回应用程序设置中的

General
页面,然后向下滚动到
Private keys
部分。点击
Generate a private key
按钮;这将立即生成一个
.pem
文件并将其下载到您的计算机。

请勿将其提交到您的存储库,除非您希望每个可以看到该存储库的人都能够像您一样向 GitHub 进行身份验证。

代码

一旦掌握了这三件事,代码中需要的步骤是:

  1. 加载您的PEM
  2. 使用 PEM 创建 JSON Web 令牌来验证您的 API 调用
  3. 调用 GitHub API 获取安装令牌
  4. (使用安装令牌克隆感兴趣的存储库。)

获取安装令牌

执行前三个步骤的代码可能如下所示:

from datetime import datetime
import jwt
import requests

def get_installation_access_token(
    pem_filename: str, app_id: str, installation_id: str
) -> str:
    """
    Obtain and return a GitHub installation access token.

    Arguments:
        pem_filename: Filename of a PEM file generated by GitHub to
                      authenticate as the installed app.
        app_id: The application ID
        installation_id: The ID of the app installation.

    Returns:
        The installation access token obtained from GitHub.
    """

    # With thanks to https://github.com/orgs/community/discussions/48186
    now = int(datetime.now().timestamp())
    with open(pem_filename, "rb") as pem_file:
        signing_key = jwt.jwk_from_pem(pem_file.read())
    payload = {"iat": now, "exp": now + 600, "iss": app_id}
    jwt_instance = jwt.JWT()
    encoded_jwt = jwt_instance.encode(payload, signing_key, alg="RS256")

    response = requests.post(
        "https://api.github.com/app/installations/" f"{installation_id}/access_tokens",
        headers={
            "Authorization": f"Bearer {encoded_jwt}",
            "Accept": "application/vnd.github+json",
            "X-GitHub-Api-Version": "2022-11-28",
        },
    )
    if not 200 <= response.status_code < 300:
        raise RuntimeError(
            "Unable to get token. Status code was "
            f"{response.status_code}, body was {response.text}."
        )

    return response.json()["token"]

将上面收集到的信息作为三个参数传入到函数中。请注意,这取决于

jwt
requests
软件包,它们都可以在
pip
中以这些名称使用。

这将提供一个有效期为一小时的安装令牌。 (这比 PEM 文件的有效时间要短得多,因为它的安全性要低得多。这就是需要这种舞蹈的原因 - 您正在用相当安全的东西来交换安全性较低但更易于使用的东西

git clone
;因为它不太安全,所以必须有时间限制,以减少被盗的机会。)

克隆存储库

假设您有表单中的存储库 URL

repo_url = https://github.com/organization/repository_name

然后您可以将存储库克隆为:

import git

if not original_url.startswith("https://"):
    raise ValueError("Need an HTTPS URL")

auth_url = f"https://x-access-token:{token}@{original_url[8:]}"
git.Repo.clone_from(
    auth_url,
    deployment["tempdir_path"] / "repo",
    branch="deployment",
)

这里我使用了 Python 的

GitPython
库。同样,您可以使用 shell 命令

$ git clone https://x-access-token:${TOKEN}@github.com/organization/repository_name

其中

${TOKEN}
包含调用上述Python函数的结果。

学分

非常感谢 GitHub 社区上的 loujr 提供的指南,最终指导我如何做到这一点。我不再需要使用命令行参数并手动将 JWT 传递到 curl

,而是将所有内容都保留在 Python 中。

© www.soinside.com 2019 - 2024. All rights reserved.