深入浅出Git权限校验
http://debugtalk.com/post/head-first-git-authority-verification/
http://debugtalk.com/post/head-first-git-authority-verification/
http://debugtalk.com/post/head-first-git-authority-verification/
借助上次“掉坑”的经历,我对Git权限校验的两种方式重头进行了梳理,形成了这篇总结记录。
在本地计算机与GitHub(或GitLab)进行通信时,传输主要基于两种协议,HTTPS
和SSH
,对应的仓库地址就是HTTPS URLs
和SSH URLs
。
HTTPS URLs
GitHub官方推荐采用HTTPS URLs
的方式,因为该种方式适用面更广(即使在有防火墙或代理的情况下也同样适用),使用更方便(配置更简单)。
在Mac系统中,在启用Keychain
机制的情况下,首次输入GitHub账号密码后,认证信息就会自动保存到系统的Keychain
中,下次再次访问仓库时就会自动读取Keychain
中保存的认证信息。
| |
SSH URLs
除了HTTPS URLs
,还可以采用SSH URLs
的方式访问GitHub代码仓库。
| |
在创建秘钥的过程中,系统还建议创建一个名为passphrase
的东西,这是用来干嘛的呢?
首先,单独采用密码肯定是不够安全的。如果密码太简单,那么就很容易被暴力破解,如果密码太复杂,那么用户就很难记忆,记录到小本子里面更不安全。
秘钥对创建好以后,私钥存放于本地计算机(~/.ssh/id_rsa
),将公钥(~/.ssh/id_rsa.pub
)中的内容添加至GitHub账户。
| |
不过,如果此时检测本地计算机与GitHub的连接状态,会发现系统仍提示权限校验失败。
| |
| |
| |
再次检测本地计算机与GitHub的连接状态,校验就正常通过了。
| |
后续再进行clone
/fetch
/pull
/push
操作时,就可以正常访问GitHub代码仓库了,并且也不需要再重新输入账号密码。
而且,将私钥加入ssh-agent
后,即使删除私钥文件,本地计算机仍可以正常访问GitHub代码仓库。
| |
只有执行ssh-add -D
或ssh-add -d pub_key
命令,将私钥从ssh-agent
删除后,认证信息才会失效。
| |
同时使用多个GitHub账号
熟悉了HTTPS URLs
和SSH URLs
这两种校验方式之后,我们再来看之前遇到的问题。要想在一台计算机上同时使用多个GitHub账号访问不同的仓库,需要怎么做呢?
前面已经说过,HTTPS URLs
和SSH URLs
对应着两套独立的权限校验方式,因此这两套方式应该是都能单独实现我们的需求的。
不过在详细讲解Git权限校验的问题之前,我们先来回顾下Git配置文件的优先级。
Git配置存储位置及其优先级
Unix-like
系统中,保存Git用户信息的主要有3个地方(Mac系统多一个Keychain
):
/etc/gitconfig
:存储当前系统所有用户的git配置信息,使用带有--system
选项的git config
时,配置信息会写入该文件;~/.gitconfig
或~/.config/git/config
:存储当前用户的git配置信息,使用带有--global
选项的git config
时,配置信息会写入该文件;Keychain Access
:在开启Keychain
机制的情况下,进行权限校验后会自动将账号密码保存至Keychain Access
。- 仓库的Git目录中的config文件(即
repo/.git/config
):存储当前仓库的git配置信息,在仓库中使用带有--local
选项的git config
时,配置信息会写入该文件;
基于SSH
协议实现多账号共存
在处理多账号共存问题之前,两个账号均已分别创建SSH
秘钥对,并且SSH-key
均已加入本地计算机的ssh-agent
。
| |
在详细讲解多账号共存的问题之前,我们先来回想下平时在Terminal中与GitHub仓库进行交互的场景。
| |
在操作过程中,本地计算机的ssh-agent
与GitHub服务器建立了连接,并进行了账号权限校验。
当本地计算机只有一个GitHub账号时,这个行为并不难理解,系统应该会采用这个唯一的GitHub账号进行操作。那如果本地计算机中有多个Github账号时,系统是根据什么来判断应该选择哪个账号呢?
实际情况是,系统没法进行判断。系统只会有一个默认的账号,然后采用这个默认的账号去操作所有的代码仓库,当账号与仓库不匹配时,就会报权限校验失败的错误。
那要怎样才能让系统正确区分账号呢?这就需要我们手动进行配置,配置文件即是~/.ssh/config
。
| |
要理解以上配置文件的含义并不难,我们可以对比看下两个项目的SSH URLs
:
| |
其中,git
是本地ssh-agent
与GitHub服务器建立SSH
连接采用的用户名(即User
),github.com
是GitHub服务器的主机(即HostName
)。
可以看出,如果采用原始的SSH URLs
,由于User
和HostName
都相同,本地计算机并不知道应该采用哪个SSH-key
去建立连接。
| |
不过,我们还遗漏了很重要的一点。在本地代码仓库中执行push
/pull
/fetch
等操作的时候,命令中并不会包含Host
信息,那系统怎么知道我们要采用哪个GitHub账号进行操作呢?
显然,不同的仓库可能对应着不同的GitHub账号,因此这个配置不能配置成全局的,而只能在各个项目中分别进行配置,即repo/.git/config
文件。
| |
| |
配置的原理也很容易理解,就是将仓库的Host
更换为之前设置的别名。添加完毕后,后续再在两个仓库中执行任何git
操作时,系统就可以选择正确的SSH-key
与GitHub服务器进行交互了。
基于HTTPS
协议实现多账号共存
不管是存储到哪里,我们面临的问题都是相同的,即如何在代码仓库中区分采用哪个GitHub账号。
| |
| |