在哪里存储我的 Git 个人访问令牌?

Where to store my Git personal access token?

在 GitHub 中生成个人访问令牌后,是否需要将其存储在机器本地的某个位置?

如果是,是否有任何首选的存储方式?

好吧,如果您不想每次应用程序请求时都输入令牌,那么您必须将令牌 保存在某个地方 :-)

一个好的解决方案是使用环境变量,正如 中已经建议的那样。

但是你还是得在某处设置环境变量。
在Windows(我正在使用的)上,你可以使用系统设置中的dialog box (我不知道其他操作系统是否有类似的东西).

我不这样做,我更喜欢在我的项目中使用脚本。
在私有项目中,您可以将其提交给源代码管理,但这是一个偏好问题。

在我的一个个人项目中,我也使用个人访问令牌调用 GitHub API。
这是一个命令行应用程序,最终用户会将令牌保存在配置文件中 (没问题).

但我也需要开发令牌,因为项目有集成测试,我在其中调用 GitHub API.

那个项目是 GitHub 上的 public,所以我无法在源代码管理中保存令牌。

我做的是这样的:

  • 我有一个名为 environment-variables.bat 的批处理文件 (记住,我在 Windows) 上设置了所有必需的环境变量,包括访问令牌
  • 我在我的 build script and in the batch file 中调用它 我正在使用 运行 我的测试
  • environment-variables.batignored in source control
  • 但是在源代码管理中,有 environment-variables.bat.sample,它包含相同的内容,但是是假的 token/password。

所以我可以将此文件重命名为 environment-variables.bat,将假密码替换为真实密码,一切正常。


不过,这并不是适用于所有情况的完美解决方案。

在我的项目中,我遇到了一个问题,我需要在未来使用更多的 tokens/passwords 来获得更多的 API。

因此我的 environment-variables.bat 中的令牌数量将 增加,使潜在的贡献者很难实际执行所有集成测试。而我还是don't know how to deal with that.

基本上我是在我的机器上这样做的:

https://gist.github.com/bsara/5c4d90db3016814a3d2fe38d314f9c23

我的个人资料脚本与描述的略有不同:

env=~/.ssh/agent.env

agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }

agent_start () {
    (umask 077; ssh-agent >| "$env")
        . "$env" >| /dev/null ; 
}

agent_load_env

# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2= agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)

if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
    agent_start
    ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
    ssh-add
fi

unset env

Half the point of passwords is that (ideally) you memorize them and the system hashes them, so therefore they're never stored anywhere in plain text.
Yet GitHub's personal access token system seems to basically force you to store the token in plain text?

首先,PAT (Personal Access Token) 不是一个简单的密码,而是一个等价于:

  • 您可以生成多个时间(例如,每台机器一个,您需要从中访问 GitHub 存储库)
  • 您可以随时 撤销(从 GitHub 网络界面),这会使 PAT 过时,即使它在其中一台机器上徘徊.

这与您的密码不同,后者对您的帐户而言是唯一的,并且无法轻易更改,而无需在您碰巧使用它的任何地方修改它。


由于在命令行上使用 Git 或 API 通过 HTTPS 执行 Git 操作时可以使用 PAT 代替密码,因此您可以使用 git credential helper 安全地缓存它。
例如,在 Windows 上,将使用 the Windows Credential Manager, through the GCM -- Git Credential Manager -- for Windows, Mac or Linux:

git config --global credential.helper manager-core

第一次推送到存储库时,弹出窗口会要求您提供凭据:用户名 您的 PAT。
下一次,它不会询问,而是直接重复使用该 PAT,它仍然安全地存储在您的凭据管理器中。

类似的想法适用于 Mac with the OSX keychain, and Linux with the GNOME Keyring (in 2021, it would need a DBus session and libsecret),但在 2021 年,GCM-Core 涵盖了这些用例。
这个想法仍然存在:将 PAT 存储在 加密的 凭据存储中。


如上所述,更现代的解决方案(2020 年第 4 季度)是 Microsoft Git-Credential-Manager-Core

git config --global credential.helper manager-core

您需要它来安装 git-credential-manager-core,下载它的 latest release, like gcmcore-linux_amd64.2.0.474.41365.deb

sudo dpkg -i <path-to-package>
git-credential-manager-core configure

尽管如 Mekky Mayata in 所述,在 Linux 上使用 GCM(Git-Credential-Manager-Core),您需要先定义一个 git config --global credential.credentialStore

参见“Credential stores on Linux”:

There are four options for storing credentials that Git Credential Manager (GCM) manages on Linux platforms:

By default, GCM comes not configured.
You can select which credential store to use by setting the GCM_CREDENTIAL_STORE environment variable, or the credential.credentialStore Git configuration setting.

agent18 in the comments 所述,在安装 libsecret-1-0libsecret-1-dev 之后使用 git-credential-libsecret 是很好的第一步。
但是,同样,现在应该由 credential-manager-core.

包装

我喜欢在存储库中将它们加密并使用 .envrc (https://direnv.net/)

加载它们

为此,我使用 ssh-vault to encrypt the data using my ssh keys that GitHub already is exposing,例如:

echo MY_TOKEN="secret" | ssh-vault -u <github-user> create > my-encypted-vars.ssh

然后 .envrc 的内容看起来像这样:

echo "Enter ssh key password"
context=$(ssh-vault view $HOME/projects/my-encrypted.ssh | tail -n +2)
export ${context}

每次我 cd 进入项目目录时,这将解密 my-encrypted-vars.ssh 文件中的数据并将 MY_TOKEN 设置到我的环境变量中。

通过这样做 tokens/variables 被存储 "safely" 并随时准备用作环境变量

就我而言,在 Ubuntu 中,接受的解决方案不适用于

这样的消息

git: 'credential-manager' is not a git command

但是 store 而不是 manager 效果很好:

git config --global credential.helper store

您可以使用以下方式在定义的时间内缓存您的凭据:

git config --global credential.helper cache

默认缓存周期为 900 秒(15 分钟),但可以通过以下方式更改:

git config --global credential.helper 'cache --timeout=3600'

查看以下 Github 页面:

https://docs.github.com/en/github/using-git/caching-your-github-credentials-in-git

这不是永久存储,根据其他评论,凭据不应以纯文本形式存储,这存在安全风险。我使用密码管理器(https://bitwarden.com/) to store the PAT (Personal Access Token) 然后将其复制以供首次使用,然后将其缓存。如果您在 Github 帐户上启用 2FA,则需要 PAT。

Ubuntu 20.04 上测试,几乎全新安装,Git 2.25.1 和 unity 7.5。

身份验证基础知识

Git集线器需要一个身份验证密钥(某些权限与所述身份验证密钥相关联)。特定的授权密钥具有某些权限(读取私有存储库、读写 public 存储库等...)和“充当密码”以及可以在用户需要时撤销的权限。

个人访问令牌

  1. 我们先做一个 PAT。 I.E.,设置 --> 开发人员设置 --> Persaonl 访问令牌 --> 生成新令牌 --> 注意 --> 设置权限(repo,repo_hook 可能)--> 生成令牌
  2. git push repo 并在询问时输入生成的令牌(非常长的密码)作为密码。

以不同方式存储密码

    • 可以在文件中完成,然后使用 xclip 将其带回剪贴板并每次粘贴(去他妈的)
    • 缓存 help of git commands git config credential.helper cache <time-limit-of-cache>。但是你仍然需要在时间限制后以某种方式将密码剪贴板。
    • 将其永久存储在文件中 with git commands git config credential.helper store(不要使用 --global)。这不是加密的。您可以打开文件并阅读它。 (例如,如果有人可以访问您的笔记本电脑,他们几乎可以使用可启动 USB 读取密码(假设您的整个系统未加密))。
    • 或者按照here走加密路线。它一点也不复杂。 3 个简单步骤。
sudo apt-get install libsecret-1-0 libsecret-1-dev
sudo make --directory=/usr/share/doc/git/contrib/credential/libsecret
    
git config credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

这允许以加密格式存储 password/personal 访问令牌。 git config 文件可以在您的本地存储库的 .git/config 文件中找到,如 here 所示,如果您需要的话。

P.S。 有很多地方建议使用Gnome-keyring but that is apparently deprecated.

为多个帐户存储passwords/PATs

这变得很棘手,它看起来像@VonC 建议我们需要一个 Git-Credential-Manager core(GCM 核心)。这个答案是根据我在 .

中的发现得到增强的
  1. 第一个

    1. 下载latest .deb package
    2. sudo dpkg -i <path-to-package>
    3. git-credential-manager-core configure
    4. git config --global credential.credentialStore secretservice 因为我们使用 libsecret
  2. 获取最新的git

    在我的例子中,我有 git 2.25 并得到错误 error: unknown option 'show-scope'。看来 GCM 核心正在使用更高的 git (至少 2.26)。

    所以根据 here:

    安装最新最好的 git
     sudo add-apt-repository ppa:git-core/ppa
     sudo apt-get update
     apt list git # shows the latest git currently 2.31
     sudo apt-get install git #or sudo apt-get upgrade
    
  3. 使用内置用户名更新git远程路径

    GCM 核心需要这个来识别不同的帐户。:(

     git remote set-url origin https://user1@github.com/user1/myRepo1.git
     git remote set-url origin https://user2@github.com/user1/myRepo1.git
                                   ^^^^^
    

您的 ~/.gitconfig 文件将因此具有以下内容:

[credential]
   helper = /usr/bin/git-credential-manager-core
   credentialStore = secretservice
[credential "https://dev.azure.com"]
   useHttpPath = true

或者,您可以在主目录中创建一个 ~/.netrc 文件并将您的登录凭据保存到其中。

cat ~/.netrc
machine github.com login <login-id> password <token-password>

您可以存储 github https token using pass

将 git 主机映射到通行证条目的两种选择:

  • bash 脚本映射到右侧 pass 条目:
#!/usr/bin/env bash
# assuming "get" action from git and a config like this
# git config --global credential.helper $XDG_BIN_HOME'/git_credentials_from_pass $@'
while IFS= read -r line
do
  echo "$line"
  if [[ "$line" =~ host=.*github.com.* ]]; then
      echo "username=your_user_name"
      echo "password=$(pass show token_github.com/your_username)"
  #else ...
  fi
done

更改 your_usernametoken_github.com 的设置方式 pass insert

这会将令牌添加到 pass 而无需键入或粘贴两次:

echo your_github_token | sed p | pass add token_github.com/your_username
git config --global credential.helper '!pass-git-helper $@'

pass-git-helper 需要一个 ini 文件来映射 git 请求和 pass 条目。 ${XDG_CONFIG_HOME}/pass-git-helper/git-pass-mapping.ini 示例:

[DEFAULT]
username_extractor=entry_name
[github.com*]
target=token_${host}/your_github_username

尝试启用此功能以帮助在推送/拉取过程中保持持久性

git config credential.helper store

为了持续克隆 repo / 对于 macOS 用户 / 安装 iTerm2 https://iterm2.com/

启用工具带

只需在需要时单击该代码段即可。 P.S。你正在使用 oh-my-zsh,不是吗? https://github.com/ohmyzsh/ohmyzsh

要将您的凭据存储在缓存中并避免每次执行 git 操作时都登录,请执行以下步骤:

  1. 导航到您的本地存储库文件夹。
  2. 在当前文件夹的终端中:git config --global --replace-all credential.helper cache
  3. 执行git pushgit pull
  4. 使用用户名和访问令牌登录(访问令牌是您的密码)。令牌可以在 GitHub 中设置并可以访问 repo、工作流、write:packages 和 delete:packages.
  5. 重复 git push 或任何 git 操作,您会发现从现在开始它不再要求登录凭据。

在我的用例中,我将 PAT 存储在密码管理器中,例如LastPass、KeePass、1Password。当我在 Linux 环境(例如 Docker )中需要它时,我将 PAT 保存在环境变量中,然后使用 git 的凭据帮助程序设置。例如:

git config --global credential.helper 'cache --timeout 600'

<< eof tr -d ' ' | git credential-cache store 
  protocol=https
  host=github.com
  username=nonce
  password=${GITHUB_PAT}
eof

对于 PAT,用户名可以是除空白以外的任何内容。这是一个详细说明的要点:

https://gist.github.com/rwcitek/da862e9e27cc28d3e96e62a2ca4b2b64