多个Git账户免密码登录配置
多个 Git 账户免密码登录配置
摘要
目前使用 git 作为文件版本控制工具的开发者越来越多,同时一个开发者可以拥有多个不同 git 服务器的帐号或者同一个 git 服务器的不同帐号。
例如,小明在公司有个公司搭建的 git 服务器帐号用于工作开发,同时在目前流行的 github 和 bitbucket 上也有帐号,在业余时间 fork 一些项目,然后做一些 contributes. 这时小明就会遇到一个问题,账户这么多,如果每次使用 git 软件在终端进行 add, commit 后,需要 push 到本地仓库对应的远程服务器时,如果没有事先配置好 ssh 免密码登录或是其他密钥管理方法, 每次都需要输入对应的服务器账户密码来进行安全认证。
有没有什么方法可以一劳永逸地解决这个多 git 账户自动匹配免密码登录问题呢?
本文描述了在 Terminal 环境下使用 ssh 协议的多个不同 git 服务器帐号的 git 仓库如何自动匹配免密码登录的方法。
快速预览
主要解决两个问题,免密码登录 和 多账户自动匹配,前者可以使用 ssh 公私钥对解决,后者通过编辑 ssh 配置文件解决。
场景模拟
小明目前有 3 个 git 服务器账户,账户信息分别如下:
- 第 1 个是公司购买的 bitbucket 付费账户,用于日常工作开发, 其账户名为
xiaoming
, 关联邮箱为xiaoming@test.com
,
目前工作项目的仓库地址为git@bitbucket.org:xiaoming/testFly.git
. - 第 2 个是自己私人申请的免费 bitbucket 账户, 用于管理和保存私人的配置文件等或者 fork 一些项目研究做些贡献,其账户名为
superming
,关联邮箱为
superming@gmail.com
, 目前关注的项目仓库地址是git@bitbucket.org:superming/superman.git
. - 第 3 个账户也是自己私人申请的免费 github 账户,这里是开源的天堂,小明经常在此 star, watch, fork 项目等,其账户名为
mingh
, 关联邮箱为
mingh@gmail.com
.
为了实现这 3 个账户自动匹配免密码登录,小明首先依次生成了三对密钥文件:
1 | 生成第 1 个名为 xiaoming 账户的密钥对 |
接着手动添加了这 3 对密钥对的私钥文件到 ssh-agent
会话用于自动认证 ssh
会话连接:
1 | ssh-add ~/.ssh/id_rsa_xiaoming |
由于 ssh-agent
会话是一个临时的会话,在终端退出后也随之结束,为了每次启动终端时都能自动添加私钥文件:
1 | echo "ssh-add ~/.ssh/id_rsa_xiaoming >/dev/null 2>&1" >> ~/.bashrc |
由于小明用的是 zshell
, 需要把 ~/.bashrc
改成 ~/.zshrc
.
接下来就要配置 ~/.ssh/config
配置文件实现账户自动匹配:
1 | # 第 1 个 xiaoming bitbucket 工作账户 |
由于工作账户新项目创建不频繁,所以使用了 xiaoming_work
作为 host
, 但同时需要到当前工作的项目的根目录修改远程服务器地址:
1 | 原远程服务器 origin 地址为 git@bitbucket:xiaoming/testFly.git |
而 host
与 hostname
一致的两个常用账户则不需要修改远程服务器地址了。
为了保证对应账户下的 git 仓库使用对应的账户名和邮箱进行 commit
, push
等,
还需要进行每个 git 仓库设置对应的 user.name
和 user.email
:
1 | cd <testFly 仓库根目录> |
方法详解
- 为指定 git 账户生成 ssh 密钥文件实现免密码登录
1 | ssh-keygen -t rsa -f ~/.ssh/id_rsa_work -C "work@163.com"` |
-t rsa
指定生成密钥类型(type)为 rsa 非对称加密;-f ~/.ssh/id_rsa_work
指定生成密钥存放文件(file)为~/.ssh/id_rsa_work
, 该文件名可以由用户自己命名,
建议该文件统一放在~/.ssh/
目录下以便于管理;-C "work@163.com"
给该密钥添加注释(comment),一般使用关联该 git 账户的 email.
执行此命令后需要你输入要生成的密钥文件的口令(密码)和重复输入口令,连按回车键即可设置密钥文件口令为空从而实现免密码登录。
然后你就会在~/.ssh
目录下找到新生成的密钥文件分别为id_rsa_work
和id_rsa_work.pub
, 前者为私钥文件,本地私人使用,后者为公钥文件,
可以公开使用。
- 添加上述私钥文件到当前 ssh-agent 会话用于认证 ssh 会话
1 | ssh-add ~/.ssh/id_rsa_work |
- 查看当前会话已添加的 ssh 私钥
1 | ssh-add -L |
- 每次启动终端时都自动添加指定私钥到当前 ssh-agent 会话中
1 | echo "ssh-add ~/.ssh/id_rsa_work >/dev/null 2>&1" >> ~/.bashrc |
如果使用 zshell
1 | echo "ssh-add ~/.ssh/id_rsa_work >/dev/null 2>&1" >> ~/.zshrc |
- 配置
~/.ssh/config
文件实现多 git 账户自动匹配认证登录
编辑~/.ssh/config
ssh 配置文件(如果没有该文件就手动新建,touch ~/.ssh/config
),
以 bitbucket 帐户为例,例如账户work
下的一个 git 仓库地址为:git@bitbucket.org:work/test.git
, 从仓库地址可以看出此仓库的
用户名(User
)为git
, 主机名(hostname
)为bitbucket.org
, 通信端口号(Port
)一般为22
.所以其配置为:
1 | # 此处演示 bitbucket 下注册的账户名为 work 的账户的 ssh 配置 |
其中 hostname
, User
, Port
对应于 git 仓库地址里的信息,而 host
可以认为是一个别名,表示了这一主机的别名,
可随意命名,用于区分具有同一个 hostname
的不同账户的仓库。IdentityFile
为私钥认证文件,即上文生成的 id_rsa_work
文件.
部署公钥到 git 服务器
例如在 bitbucket 服务器网页上菜单bitbucket Settings > SSH keys > Add key
,
把公钥文件里的公钥字符串拷贝粘贴到此处设置处.1
2拷贝公钥字符串到系统剪贴板,此处是 macOS 的系统剪贴板
cat ~/.ssh/id_rsa_work.pub | pbcopy测试 ssh 能否免密码直连
1
ssh -vT git@bitbucket.org
或者使用
git clone
一个当前账户下的私人项目到本地看是否成功。修改本地 git 仓库的远程服务器地址
如果你在 github 或者 bitbucket 服务器上都只注册了一个账户,在配置
~/.ssh/config
时建议host
与hostname
保持一致,
如此不用修改配置。如果你在同一个 git 服务器上有两个账户,例如在 bitbucket 上有常用的
1
work
账户和不太常用的
1
life
账户,
1
~/.ssh/config
可以配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13# personal git account "work" in bitbucket
host git@bitbucket.org
hostname bitbucket.org
Port 22
User git
IdentityFile "~/.ssh/id_rsa_work"
# personal git account "life" in bitbucket
host lifebucket
hostname bitbucket.org
Port 22
User git
IdentityFile "~/.ssh/id_rsa_life"使用上述配置,对于要新
clone
的work
账户下的仓库或是本地已存在的仓库,不需要修改任何配置,因为host
与hostname
一样。对于
1
life
账户下的仓库:
- 新 clone 的仓库需要修改仓库地址url,例如
git clone git@bitbucket.org:life/tutorial.git
改为git clone lifebucket:life/tutorial.git
- 已经存在的仓库,切换到该仓库根目录,执行
git remote remove origin && git remote add origin lifebucket:life/tutorial.git
.
- 新 clone 的仓库需要修改仓库地址url,例如
git 设置
由于有多个不同的 git 账户,一般不能随意设置 git 全局设置了,尤其是
1
user.name
和
1
user.email
,需要单独给每个仓库设置。
首先移除全局设置:
1
git config --global --unset user.name && git config --global --unset user.email
,
然后到对应的仓库根目录下执行类似于下面的命令:
1
2git config --local user.name "life"
git config --local user.email "life@163.com"