Git 工具 - 凭证存储
凭证存储
如果你使用的是 SSH 方式连接远端,并且设置了一个没有口令的密钥,这样就可以在不输入用户名和密码的情况下安全地传输数据。 然而,这对 HTTP 协议来说是不可能的 —— 每一个连接都是需要用户名和密码的。 这在使用双重认证的情况下会更麻烦,因为你需要输入一个随机生成并且毫无规律的 token 作为密码。
幸运的是,Git 拥有一个凭证系统来处理这个事情。 下面有一些 Git 的选项:
默认所有都不缓存。 每一次连接都会询问你的用户名和密码。
“cache” 模式会将凭证存放在内存中一段时间。 密码永远不会被存储在磁盘中,并且在15分钟后从内存中清除。
“store” 模式会将凭证用明文的形式存放在磁盘中,并且永不过期。 这意味着除非你修改了你在 Git 服务器上的密码,否则你永远不需要再次输入你的凭证信息。 这种方式的缺点是你的密码是用明文的方式存放在你的 home 目录下。
如果你使用的是 Mac,Git 还有一种 “osxkeychain” 模式,它会将凭证缓存到你系统用户的钥匙串中。 这种方式将凭证存放在磁盘中,并且永不过期,但是是被加密的,这种加密方式与存放 HTTPS 凭证以及 Safari 的自动填写是相同的。
如果你使用的是 Windows,你可以安装一个叫做 “winstore” 的辅助工具。 这和上面说的 “osxkeychain” 十分类似,但是是使用 Windows Credential Store 来控制敏感信息。 可以在 https://gitcredentialstore.codeplex.com 下载。
你可以设置 Git 的配置来选择上述的一种方式
$ git config --global credential.helper cache
部分辅助工具有一些选项。 “store” 模式可以接受一个 --file <path> 参数,可以自定义存放密码的文件路径(默认是`~/.git-credentials`)。 “cache” 模式有 --timeout <seconds> 参数,可以设置后台进程的存活时间(默认是 “900”,也就是 15 分钟)。 下面是一个配置 “store” 模式自定义路径的例子:
$ git config --global credential.helper store --file ~/.my-credentials
Git 甚至允许你配置多个辅助工具。 当查找特定服务器的凭证时,Git 会按顺序查询,并且在找到第一个回答时停止查询。 当保存凭证时,Git 会将用户名和密码发送给 所有 配置列表中的辅助工具,它们会按自己的方式处理用户名和密码。 如果你在闪存上有一个凭证文件,但又希望在该闪存被拔出的情况下使用内存缓存来保存用户名密码,.gitconfig 配置文件如下:
[credential]
helper = store --file /mnt/thumbdrive/.git-credentials
helper = cache --timeout 30000
底层实现
这些是如何实现的呢? Git 凭证辅助工具系统的命令是 git credential,这个命令接收一个参数,并通过标准输入获取更多的参数。
举一个例子更容易理解。 我们假设已经配置好一个凭证辅助工具,这个辅助工具保存了 mygithost 的凭证信息。 下面是一个使用 “fill” 命令的会话,当 Git 尝试寻找一个服务器的凭证时就会被调用。
$ git credential fill (1)
protocol=https (2)
host=mygithost
(3)
protocol=https (4)
host=mygithost
username=bob
password=s3cre7
$ git credential fill (5)
protocol=https
host=unknownhost
Username for 'https://unknownhost': bob
Password for 'https://bob@unknownhost':
protocol=https
host=unknownhost
username=bob
password=s3cre7
这是开始交互的命令。
Git-credential 接下来会等待标准输入。 我们提供我们所知道的信息:协议和主机名。
一个空行代表输入已经完成,凭证系统应该输出它所知道的信息。
接下来由 Git-credential 接管,并且将找到的信息打印到标准输出。
如果没有找到对应的凭证,Git 会询问用户的用户名和密码,我们将这些信息输入到在标准输出的地方(这个例子中是同一个控制台)。
凭证系统实际调用的程序和 Git 本身是分开的;具体是哪一个以及如何调用与 credential.helper 配置的值有关。 这个配置有多种格式:
| 配置值 | 行为 |
|---|---|
|
|
执行 |
|
|
执行 |
|
|
执行 |
|
|
|
上面描述的辅助工具可以被称做 git-credential-cache、git-credential-store 之类,我们可以配置它们来接受命令行参数。 通常的格式是 “git-credential-foo [args] <action>.” 标准输入/输出协议和 git-credential 一样,但它们使用的是一套稍微不太一样的行为:
get是请求输入一对用户名和密码。store是请求保存一个凭证到辅助工具的内存。erase会将给定的证书从辅助工具内存中清除。
对于 store 和 erase 两个行为是不需要返回数据的(Git 也会忽略掉)。 然而对于 get,Git 对辅助工具的返回信息十分感兴趣。
如果辅助工具没有任何有用的信息,它可以直接退出而不需要输出任何东西,但如果它有这些信息,它在提供的信息后面增加它所拥有的信息。 这些输出会被视为一系列的赋值语句;每一个提供的数据都会将 Git 已有的数据替换掉。
这有一个和上面一样的例子,但是跳过了 git-credential 这一步,直接到 git-credential-store:
$ git credential-store --file ~/git.store store (1)
protocol=https
host=mygithost
username=bob
password=s3cre7
$ git credential-store --file ~/git.store get (2)
protocol=https
host=mygithost
username=bob (3)
password=s3cre7
我们告诉
git-credential-store去保存凭证:当访问https://mygithost时使用用户名 “bob”,密码是 “s3cre7”。现在我们取出这个凭证。 我们提供连接这部分的信息(
https://mygithost)以及一个空行。git-credential-store输出我们之前保存的用户名和密码。
~/git.store 文件的内容类似:
https://bob:s3cre7@mygithost
仅仅是一系列包含凭证信息URL组成的行。 osxkeychain 和 winstore 辅助工具使用它们后端存储的原生格式,而 cache 使用它的内存格式(其他进程无法读取)。
自定义凭证缓存
已经知道 git-credential-store 之类的是和 Git 是相互独立的程序,就不难理解 Git 凭证辅助工具可以是 任意 程序。 虽然 Git 提供的辅助工具覆盖了大多数常见的使用场景,但并不能满足所有情况。 比如,假设你的整个团队共享一些凭证,也许是在部署时使用。 这些凭证是保存在一个共享目录里,由于这些凭证经常变更,所以你不想把它们复制到你自己的凭证仓库中。 现有的辅助工具无法满足这种情况;来看看我们如何自己实现一个。 这个程序应该拥有几个核心功能:
我们唯一需要关注的行为是
get;store和erase是写操作,所以当接受到这两个请求时我们直接退出即可。共享的凭证文件格式和
git-credential-store使用的格式相同。凭证文件的路径一般是固定的,但我们应该允许用户传入一个自定义路径以防万一。
我们再一次使用 Ruby 来编写这个扩展,但只要 Git 能够执行最终的程序,任何语言都是可以的。 这是我们的凭证辅助工具的完整代码:
#!/usr/bin/env ruby
require 'optparse'
path = File.expand_path '~/.git-credentials' (1)
OptionParser.new do |opts|
opts.banner = 'USAGE: git-credential-read-only [options] <action>'
opts.on('-f', '--file PATH', 'Specify path for backing store') do |argpath|
path = File.expand_path argpath
end
end.parse!
exit(0) unless ARGV[0].downcase == 'get' (2)
exit(0) unless File.exists? path
known = {} (3)
while line = STDIN.gets
break if line.strip == ''
k,v = line.strip.split '=', 2
known[k] = v
end
File.readlines(path).each do |fileline| (4)
prot,user,pass,host = fileline.scan(/^(.*?):\/\/(.*?):(.*?)@(.*)$/).first
if prot == known['protocol'] and host == known['host'] then
puts "protocol=#{prot}"
puts "host=#{host}"
puts "username=#{user}"
puts "password=#{pass}"
exit(0)
end
end
我们在这里解析命令行参数,允许用户指定输入文件,默认是
~/.git-credentials.这个程序只有在接受到
get行为的请求并且后端存储的文件存在时才会有输出。这个循环从标准输入读取数据,直到读取到第一个空行。 输入的数据被保存到
known哈希表中,之后需要用到。这个循环读取存储文件中的内容,寻找匹配的行。 如果
known中的协议和主机名与该行相匹配,这个程序输出结果并退出。
我们把这个辅助工具保存为 git-credential-read-only,放到我们的 PATH 路径下并且给予执行权限。 一个交互式会话类似:
$ git credential-read-only --file=/mnt/shared/creds get
protocol=https
host=mygithost
protocol=https
host=mygithost
username=bob
password=s3cre7
由于这个的名字是 “git-” 开头,所以我们可以在配置值中使用简便的语法:
$ git config --global credential.helper read-only --file /mnt/shared/creds
[user]
email = user@xxx.com
name = user
[push]
default = simple
[credential]
helper = store --file ~/.git-credentials
helper = cache --timeout 300000
[alias]
st = status -s
ci = commit
l = log --oneline --decorate -12 --color
ll = log --oneline --decorate --color --graph
lc = log --graph --color
co = checkout
br = branch
[color]
ui = true
diff = true
status = true
branch = true
interactive = true
Git 工具 - 凭证存储的更多相关文章
- 7.14 Git 工具 - 凭证存储
凭证存储 如果你使用的是 SSH 方式连接远端,并且设置了一个没有口令的密钥,这样就可以在不输入用户名和密码的情况下安全地传输数据. 然而,这对 HTTP 协议来说是不可能的 —— 每一个连接都是需要 ...
- Git凭证存储(简单易懂,一学就会,认真看)
今天给自己提了一个问题,当我们在github.com或者gitlab上面新建仓库,并克隆到本地,首次使用的时候,会被问及用户名密码,但是这两个信息存在哪里呢? 带着这个问题,我开始搜索,并在<P ...
- 版本控制工具Git工具快速入门-Linux篇
版本控制工具Git工具快速入门-Linux篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.版本管理系统的介绍 1>.版本管理系统的特点 1.1>.自动生成备份: ...
- 版本控制工具Git工具快速入门-Windows篇
版本控制工具Git工具快速入门-Windows篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 最近在学习Golang语言,之前的开发环境在linux上开发的,后来由于办公用的是w ...
- git工具学习
最近实习的时候,遇到git工具,发现好强大之前没用过,特来学习下,然后自己注册了一个github账号,结合git命令练习一下,git的安装就不说了. 学习资料来源:廖雪峰Git教程 git简介: gi ...
- Git工具详解以及与GitHub的配合使用
git和Github 概念 git --- 版本控制工具(命令). 工具介绍官方网站:http://git-scm.com 工具下载地址:http://git-scm.com/download/ gi ...
- 【转】第 02 天:在 Windows 平台必裝的三套 Git 工具
原文网址:https://github.com/doggy8088/Learn-Git-in-30-days/blob/master/docs/02%20%E5%9C%A8%20Windows%20% ...
- windows中使用Git工具连接GitHub(配置篇)
Git在源码管理领域目前占很大的比重了,而且开源的项目很多都转到GitHub上面了.例如:jQuery, reddit, Sparkle, curl, Ruby on Rails, node.js, ...
- Git详解之六 Git工具(转)
Git 工具 现在,你已经学习了管理或者维护 Git 仓库,实现代码控制所需的大多数日常命令和工作流程.你已经完成了跟踪和提交文件的基本任务,并且发挥了暂存区和轻量级的特性分支及合并的威力. 接下来你 ...
随机推荐
- RHEL7-Samba共享测试
Linux<----->windows之间共享 Samba使用2个进程 smb ip之间的通信用smb (tcp) nmb 主机名之间的通信用nmb (netbi ...
- stm32点亮LED 测试代码及目录结构
. main.c - 使用PB12, PB13, PB14, PB15, PB5, PB6, PB7 这七个PB口点亮LED. 注意PB3和PB4是特殊口, 直接调用无效. #include &quo ...
- 转:高层游戏引擎——基于OGRE所实现的高层游戏引擎框架
高层游戏引擎——基于OGRE所实现的高层游戏引擎框架 这是意念自己的毕业论文,在一个具体的实践之中,意念主要负责的是物件和GUI之外的其他游戏系统.意念才学疏陋,望众位前辈不吝赐教.由于代码质量不高. ...
- ios中自定义checkbox
//自定义button#import <UIKit/UIKit.h> @interface CKButton : UIButton @end #import "CKButton. ...
- httpclient获取响应实体和信息的封装方法(解耦更新)
转自:https://blog.csdn.net/fhaohaizi/article/details/77850302 2018年07月19日更新,主要是解耦之后方法很多地方发生了变化,httpcli ...
- servlet 让浏览器输出中文,并成功打印出来.2种方法
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; impor ...
- 剥下“java.lang.OutOfMemoryError: unable to create new native thread”的外衣 创建线程数公式(MaxProcessMemory - JVMMemory – ReservedOsMemory)
剥下“java.lang.OutOfMemoryError: unable to create new native thread”的外衣 星期一早上到了公司,据称产品环境抛出了最可爱的异常—OutO ...
- 树莓派进阶之路 (031) -字符问题(1) - GBK汉字编码表(转)
转载:http://blog.sina.com.cn/s/blog_8184e033010109ug.html 基本简介 GB码,全称是GB2312-80<信息交换用汉字编码字符集基本集&g ...
- Python之包管理工具
安装Python包的过程中,经常涉及到distutils.setuptools.distribute.setup.py.easy_install.easy_install和pip等等. distuil ...
- Javascript将html转成pdf,下载(html2canvas 和 jsPDF)
最近碰到个需求,需要把当前页面生成pdf,并下载.弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :) 项目源码地址:https://github.com/linwalker/render-h ...