Git 的 HTTPS 凭据和 SSH 密钥
摘要
- 本文写
git连接 GitHub 等远程仓库时的两种认证:HTTPS 远程用凭据助手保存令牌,SSH 远程用密钥。macOS 的凭据助手按钥匙串osxkeychain来写。本文按 Git 2.56.0。 - 令牌怎么创建见 创建 GitHub Personal Access Token。两个账号各用一把密钥见 同一台电脑使用两个 GitHub 账号。
credential.helper所在的配置文件见 Git 的用户配置 ~/.gitconfig。 - gitcredentials,Adding a new SSH key to your GitHub account。
走哪一种由远程地址决定
GitHub 从 2021 年 8 月起,HTTPS 的 git push、git pull 不再接受账号密码,密码栏要填 Personal Access Token。每次手动粘贴令牌太麻烦,所以要么把令牌交给凭据助手保存,要么改用 SSH 密钥。
1 | git remote -v |
地址是 https://github.com/... 时走凭据助手。地址是 git@github.com:... 时走 SSH 密钥,不读凭据助手。同一台机器上两种可以并存,每个仓库按自己的远程地址选择。
HTTPS:凭据助手
选择助手
--global 写入 ~/.gitconfig,这个用户的所有仓库都会使用。设置后执行一次 git pull,按提示填写用户名和令牌;之后由助手提供,不再提问。
1 | # macOS,存入钥匙串 |
Windows 安装 Git Credential Manager 后,通常已经自动配置好助手。
store 把凭据以明文写进 ~/.git-credentials,任何能读这个文件的人都能拿到令牌。只在个人机器上、并且清楚这个风险时使用。
1 | git config --global credential.helper store |
从 store 换成钥匙串
git config --global credential.helper osxkeychain 只改 ~/.gitconfig 里的 credential.helper。~/.git-credentials 不会被删除或清空。助手改成 osxkeychain 之后,Git 不再读这个明文文件,但里面的令牌还在磁盘上。确认钥匙串里已经能推送之后,再自己删掉 ~/.git-credentials。
已有仓库不用逐个重配。钥匙串按协议和主机名保存,默认不区分仓库路径。同一个 https://github.com 只在钥匙串里还没有这项时问一次,之后这个主机上的其他 HTTPS 仓库共用这一条。Git 不会把 ~/.git-credentials 里的旧记录搬进钥匙串。
查看已保存的账号
钥匙串和 ~/.git-credentials 都要看。git credential-osxkeychain 不能列出全部记录。打开「钥匙串访问」,搜索 github.com(或其他主机名)。每条的帐户是用户名,勾选「显示密码」才看得到令牌。
知道主机名时,可以先只看用户名。带 -g 的那条,以及 get、cat,会把令牌打在终端上。
1 | # 只打印 github.com 这条的用户名 |
store 留下的文件还在时,一行一条,格式是 https://用户名:令牌@主机:
1 | cat ~/.git-credentials |
gh auth status 只列出 gh 登录的账号和存放位置,不打印令牌。
清掉旧凭据
没有提问就报 Authentication failed 时,钥匙串里多半已有旧的 github.com 条目。清掉后再操作一次,就会重新提问。这条只删除钥匙串里的对应项,不动 ~/.git-credentials。
1 | printf "protocol=https\nhost=github.com\n\n" | git credential-osxkeychain erase |
和 gh 的关系
以前执行过 gh auth setup-git 时,github.com 的 HTTPS 可能仍由 gh 提供凭据,钥匙串那一条不会被用到。在仓库里看实际生效的助手和它所在的文件:
1 | git config --show-origin --get-regexp 'credential\..*helper' |
SSH:密钥
生成密钥
推荐 ed25519,密钥短、速度快。生成的是 ~/.ssh/id_ed25519(私钥)和 ~/.ssh/id_ed25519.pub(公钥)。已有同名文件时,命令会询问是否覆盖;覆盖后,旧公钥对应的服务器都要重新添加。
1 | # -C 只是备注,便于在服务器上辨认这把密钥,不必是邮箱 |
服务器只支持 RSA 时:
1 | ssh-keygen -b 4096 -t rsa -C "your_label" |
把公钥加到服务器
把 ~/.ssh/id_ed25519.pub 的整行复制到服务器的 SSH 公钥设置页。私钥 ~/.ssh/id_ed25519 留在本机,不要上传。
-
GitHub:头像 → Settings → SSH and GPG keys → New SSH key。
-
Coding:个人设置 → SSH 公钥。
-
Gitee:设置 → 安全设置 → SSH 公钥。
逐个测试。GitHub 成功时输出 Hi 用户名! You've successfully authenticated。
1 | ssh -T git@github.com |
使用 SSH 地址
新克隆时使用 git@ 开头的地址:
1 | git clone git@github.com:hanqunfeng/reactive-redis-cache-annotation-spring-boot-starter.git |
已经用 HTTPS 克隆的仓库,改远程地址即可。这条写入该仓库的 .git/config。
1 | git remote set-url origin git@github.com:用户名/仓库名.git |
ssh -T 能打出用户名,只说明这把密钥被服务器接受。推送仍然失败时,先看 git remote -v 的地址是不是 git@ 开头,以及这个账号对仓库有没有写权限。