其他

Git密码(登录凭证)的保存和重置 Mac

背景


git有时需要用户提供凭据才能操作,比如一般公司的git服务器像gitlab等都会需要提供用户名和密码才能访问,但是每次更新或提交代码都要求输入一遍用户名密码实在繁琐,本文主要介绍一下在macOS下如何避免这种频繁的重复输入。

之前配置的store方式用于存储用户名及密码,但是最近升级了一下git版本,发现记住密码功能失效了,又开始要求输入用户名及密码,于是赶紧检查了一下配置,发现credential.helper的值变成了osxkeychain,而且即使输入了也无法记住密码,原本很简单的事情,忽然感觉复杂了,索性趁此了解一下。

凭证系统


通过Git进行远程访问时,默认每次都会要求输入用户名和密码。要想对密码进行保存,需要借助git的凭证系统。git支持四种形式的凭证模式:

  • “cache” 模式会将凭证存放在内存中一段时间。 密码永远不会被存储在磁盘中,并且在15分钟后从内存中清除。
  • “store” 模式会将凭证用明文的形式存放在磁盘中,并且永不过期。 这意味着除非你修改了你在 Git 服务器上的密码,否则你永远不需要再次输入你的凭证信息。 这种方式的缺点是你的密码是用明文的方式存放在你的 home 目录下。
  • 如果你使用的是 Mac,Git 还有一种 “osxkeychain” 模式,它会将凭证缓存到你系统用户的钥匙串中。 这种方式将凭证存放在磁盘中,并且永不过期,但是是被加密的,这种加密方式与存放 HTTPS 凭证以及 Safari 的自动填写是相同的。
  • 如果你使用的是 Windows,你可以安装一个叫做 “Git Credential Manager for Windows” 的辅助工具。 这和上面说的 “osxkeychain” 十分类似,但是是使用 Windows Credential Store 来控制敏感信息。

凭证系统和 Git 本身是分开的;每种凭证模式都对应一个凭证辅助工具来对用户名、密码进行处理。

检查本地可用的凭据助手


密码保存功能主要是借助外部凭据助手,这个助手的作用就是在git服务器(一般是通过http/https访问的URL)需要用户名和密码时,它可以提供该信息,而这种凭据助手也有很多,主要是通过credential.helper属性来指定。

$ git help -a | grep credential-
   credential-cache     Helper to temporarily store passwords in memory
   credential-store     Helper to store credentials on disk
   credential-osxkeychain

可以看到,本地默认有3个助手可选,分别为credential-cachecredential-storecredential-osxkeychain

凭据助手用法


直接使用上述的助手中credential-后边的部分,例如要使用credential-cache,就配置cache,其他如store,osxkeychain

cache


cache 将凭据临时存入内存中


用法:

git config credential.helper 'cache [<options>]'

缓存的凭据在经过一段超时时间后会自动清空,可以通过Unix域套接字访问缓存,访问的权限受限于当前用户在文件系统的权限。

选项:

--timeout <seconds> 缓存凭据的秒数,默认为900秒。
--socket <path> 使用<path>联系正在运行的缓存守护程序(或者如果未启动新的缓存守护程序,则启动一个)。默认为$XDG_CACHE_HOME/git/credential/socket,除非~/.git-credential-cache/目录存在,这样会使用~/.git-credential-cache/socket。另外必须使用本地文件系统中的绝对路径。

控制守护进程:
如果希望提前退出守护进程,在凭据超时前提前清空,可以执行以下命令:

$ git credential-cache exit

示例:

# 默认设置
$ git config credential.helper cache
# 指定超时时间为30min
$ git config credential.helper 'cache --timeout=1800'

store


store 将凭据存入磁盘

用法:

git config credential.helper 'store [<options>]'

使用此助手会将密码明文存储在磁盘上,安全依赖于文件系统权限,如果这点不可接受,请选择cacheosxkeychain或其他安全的存储方式。

选项

--file=<path> 使用<path>查找和存储凭据。该文件依赖操作系统的权限访问,但不会加密。如果没有指定,默认会依次查找~/.git-credentials$XDG_CONFIG_HOME/git/credentials,写的顺序也是一样。但是当清空凭据时,将会从所有文件中清除。


示例

# 默认设置
$ git config credential.helper store

.git-credentials文件内容格式
.git-credentials文件以纯文本格式存储。每个凭据都作为URL存储在单独的一行中:

https://user:pass@example.com

osxkeychain


如果你的系统中没有安装osxkeychain辅助工具,则需要先行安装。

curl http://github-media-downloads.s3.amazonaws.com/osx/git-credential-osxkeychain -o git-credential-osxkeychain
sudo mv git-credential-osxkeychain /usr/local/bin
sudo chmod u+x /usr/local/bin/git-credential-osxkeychain

如果习惯使用命令行进行git操作,可以通过以下命令启用凭证存储。以下均以 osxkeychain(钥匙串) 存储方式为例进行:

  • 启用 osxkeychain (钥匙串)存储:
$ git config --global credential.helper osxkeychain

执行命令后在git的全局配置文件 ~/.gitconfig 中会添加如下内容。

[credential]
	helper = osxkeychain
  • 配置后,正常情况下,我们在通过git命令进行远程操作(如git pull)时,会提示输入用户名、密码;验证成功后该凭证会保存到系统的钥匙串中。如下图:
  • 凭证保存后,下次进行远程操作时就不会提示输入用户名、密码。

凭证删除

可以直接从钥匙串访问app选中要删除的凭证,右键删除。也可以通过命令删除,空行代表命令结束。

$ git credential reject
protocol=http
host=git.jd.com

删除凭证后,下次登录时会重新提示输入用户名、密码。

多模式共存情况的处理


以上两个示例均采用单一凭证处理模式,其实是可以同时采用多种凭证存储模式的。

如果同时存在两种凭证存储方式

  • 查询时会按顺序执行各凭证辅助工具进行查询,遇到第一个应答则退出查询;
  • 保存时会调用所有的凭证辅助工具,各辅助工具根据自己的逻辑处理用户名、密码。

如果你在闪存上有一个凭证文件,但又希望在该闪存被拔出的情况下使用内存缓存来保存用户名密码,.gitconfig 配置文件如下:

[credential]
    helper = store --file /mnt/thumbdrive/.git-credentials
    helper = cache --timeout 30000

检查当前使用的助手


$ git config  -l |grep credential.helper
credential.helper=osxkeychain

看到这里,我决定就使用当前设置了,但问题来了,输入密码保存无效啊,不管是直接从shell中,还是Idea中,每次更新依然提示输入用户名密码,根本不会保存下来。如果你也遇到这个问题,请继续往下看。

既然每次都提示,怀疑是钥匙串中没有保存密码,于是打开钥匙串,搜索相关地址和用户名,果然没有:

既然不能自动保存,那就手动添加一个吧,点击左上角+(或者点击文件->新建密码项...),根据提示填写如下信息:

但当点击添加时,却一直报错,提示权限错误,多次查找无果,偶然发现左侧的小锁图标是开着的,于是右键锁定钥匙串"登录"后重新添加了一下,终于,这次弹出授权确认框,输入当前用户密码确认后添加成功!

然后执行一下git fetch命令也弹出了git-credential-osxkeychain访问授权的窗口,而不是简单的询问git的用户名密码,说明生效了:

确认系统管理员密码(当前登录用户)后,点击始终允许即可。

注:锁住的”登录”钥匙串又变为了打开的状态。本次故障猜测是由于系统重启或更新后导致权限错误,未验证。