关于 git-credential

前面说了 git-config , 今天接着介绍 git 相关的一个冷知识 credential。 所有的远程仓库都肯定会有一个身份认证机制,除非是完全公开谁都可以push的仓库。 git 本地客户端和远程仓库完成身份认证的过程,都会用到 git-credential。 关于 git-credential 官方文档建议大家看一下。

SSH 还是 HTTPS ?

大多数开发人员使用 git 时会选择 ssh key ,优点是免密码,比较方便,但 deploy public key 略麻烦,尤其是需要在多个不固定的设备上访问 git remote repo 时,不管是 gitlab 还是 github 或者 bitbucket,他们的 repo hosting 均支持 SSH 和 HTTPS 两种协议,如果 HTTPS 能像 SSH 方式一样免密码(记住密码), HTTPS 要比 SSH 方式更方便,万一 SSH private key 不在手边就抓瞎了。 所以我推荐大家使用 HTTPS 方式访问远程仓库

但 HTTPS 协议无状态,每次访问都需要授权。 所以有了 git-credential

git-credential

对于一个身份认证的凭据(凭证),无非就是几个关键的信息:

  • 协议
  • 地址
  • 用户名
  • 密码

git-credential 就是用来完成对git仓库凭据的输入输出的, 凭据的存储默认也是由它来管理的,对于一个身份认证系统,面对复杂多元的互联网生态,肯定是需要有开放性的,所以 git-credential 也有 API ,提供凭据管理的第三方厂商可以通过这个 API 来实现自己的凭据管理对 Git 的支持和集成, 实现这一点,只要自己基于 API 实现一个自己的 Git credential helper 就可以了;

相当于 git-credential 是前端, 后台是 git credential helper ;

1
2
3
4
5
6
7
8
9
10
11
12
+-----------------------+
| Git code (C) |--- to server requiring --->
| | authentication
|.......................|
| C credential API |--- prompt ---> User
+-----------------------+
^ |
| pipe |
| v
+-----------------------+
| Git credential helper |
+-----------------------+

那显然, git credential helper 在 git config 中是有很多值可选的。

cache

cache 不会将凭据存储到磁盘, 顾名思义, cache 也是可以被重复读取的,但默认过期时间是 900s,如果你需要1小时内密码不过期 ,可以这样

1
$ git config credential.helper 'cache --timeout=3600'

store

store 是会将凭据存储到磁盘,而且是明文存储,所以不推荐使用该方式. 默认会从这个文件读写 ‘~/.git-credentials` ,格式是

1
https://username:password@mygitserver.com/foo.git

这个方法还有两个问题,一个是你的用户名和密码里不能有 @ 符号,所以 eamil 地址不能用,密码里也不行。
另外一个就是如果你的用户名和密码如果有中文字符,会被(git客户端以及其他GUI客户端都会读写)重写成其他编码,下一次这个文件就不能用了,可能是老版本 git 的bug。

osxkeychain

MacOS(OSX) 操作系统中,系统有自己的凭据管理工具 KeyChain,配置 credential.helper 为 osxkeychain 后,在需要用户名密码的地方会跳出 KeyChain 的登录界面,登录成功之后产生的凭据也由 KeyChain 管理,如同 Safari 一样。 凭据是加密存放的, MacOS 用户推荐这种

manager

在 widnows 中,现在也有一个系统自带的凭据管理器 Credential Manager , 使用方法和原理基本等同于 osxkeychain
git 客户端中自带的这个 Git-Credential-Manager-for-Windows 有一个不能正确处理中文用户名的 Bug ,所以请自行升级这个组件,项目地址在这里

HTTPS 方式如何记住密码

MacOS 用户

1
$ git config credential.helper osxkeychain --global

Windows 用户

1
$ git config credential.helper manager --global

Linxu 用户

1
2
$ echo "https://username:password@mygitserver.com/foo.git" > ~/.git-credentials
$ git config credential.helper store --global

其它

git credential 良好的架构设计让 git 几乎能快速与所有认证系统进行整合, 在这里 有一个用 ruby 脚本快速实现的 自定义 credential helper 实现。

更多的 helper 去 github 自己探索吧