如何设置SSH或HTTPS仓库认证?

本文介绍如何理解和设置SSH和HTTPS进行仓库认证。

Git命令行操作未授权常见问题

Git 命令行操作有两种常用的认证方式SSH和HTTPS。当Git命令行操作因为仓库未授权而失败时,会看到如下错误输出:

remote: 找不到代码库,请确认是否有权限且代码库路径正确
致命错误:无法访问 'https://codeup.aliyun.com/...':The requested URL returned error: 403

或者

找不到代码库,请确认是否有权限且代码库路径正确
致命错误:无法读取远程仓库。

请确认您有正确的访问权限并且仓库存在。

在联系管理员解决授权问题之前,开发者先要确认认证时是否使用了正确的账号,即是否使用了预期的鉴权方式进行的认证?

Git的认证方式SSH还是HTTP

对于一个已经克隆的仓库,在仓库中执行git fetchgit push命令操作时,默认连接的远程服务器是当前分支跟踪的远程服务器,或者是由origin指定的远程服务器。

首先通过git status命令查看当前分支跟踪的远程分支:

$ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。

从命令输出我们可以看出当前分支master跟踪了上游的origin/master分支。

那么origin指向的服务器地址是什么?可以使用git remote -v或者如下命令查看:

$ git remote get-url origin
gi*@codeup.aliyun.com:my/example.git

从上面的示例输出可以看到仓库的URL地址,这个地址是一个SSH协议的仓库地址。对于SSH协议,仓库地址有两种表示方法:

  • 带有SSH协议头的表示法,如:ssh://gi*@codeup.aliyun.com:22/my/example.git。其中,协议为:ssh;服务器主机名为:codeup.aliyun.com;主机端口:22(可选);登录用户名:git(可选)。URL的最后部分为仓库路径,即:my/example.git

  • 采用scp命令的地址格式,即:[user@]host:path,如:gi*@codeup.aliyun.com:my/example.git。其中,服务器主机名为:codeup.aliyun.com;登录用户名:git(可选)。冒号分隔符的右侧部分为仓库路径,即:my/example.git

对于HTTPS协议,仓库地址是标准的URL格式:https://[user]@host[:port]/path。例如:https://codeup.aliyun.com/my/example.git。其中,服务器主机名为:codeup.aliyun.com;登录用户名如果省略,会在第一次登录时询问,或者认证助手(credential-helper)通过缓存自动提供用户名。URL的最后部分为仓库路径,即:my/example.git

Git的SSH认证方式

Git的SSH认证使用公钥认证,即使用ssh-keygen命令生成SSH的公钥私钥文件,并将公钥文件上传到代码平台个人配置下,完成公钥认证。

SSH 支持通过主机别名的方式为SSH登录设定公私钥。方法是在当前用户的ssh配置文件中进行设置。例如:在Linux、macOS中SSH配置文件地址为:~/.ssh/config。下面的示例是针对云效代码平台地址配置的一个别名my.aliyun

Host my.aliyun
  User git
  HostName codeup.aliyun.com
  Port 22
  IdentityFile /Users/my/.ssh/aliyun/id_rsa

上面的示例配置了一个主机别名my.aliyun。这个主机别名仅限本地使用,不会也不能用DNS进行查询。当用户使用Git克隆仓库ssh://my.aliyun/my/example.git时,实际连接的主机是:codeup.aliyun.com;端口为:22;用户为:git;使用的SSH私钥为:/Users/my/.ssh/aliyun/id_rsa

那么有什么更加简便的方法来确认 SSH 协议下 Git 登录的用户账号是什么,以及认证使用了哪一个公私钥么?

例如对于上述地址ssh://my.aliyun/my/example.git,使用ssh登录命令,可以看到认证是否成功,以及用户名:

$ ssh my.aliyun
Welcome to Codeup, gotgit!
Connection to codeup.aliyun.com closed.

从输出可以看到云效代码平台服务器不允许SSH登录,在显示登录账号为gotgit之后服务器切断连接。

还可以在 SSH 连接命令中添加 -v参数查看认证使用的公私钥,如下:

$ ssh -v gi*@codeup.aliyun.com
... ...
debug1: Offering public key: /Users/my/.ssh/aliyun/id_rsa RSA SHA256:8lEmVm11YzWZtT1U1FRrOx3rpMN1gFpOe776biyNkrI explicit
debug1: Server accepts key: /Users/my/.ssh/aliyun/id_rsa RSA SHA256:8lEmVm11YzWZtT1U1FRrOx3rpMN1gFpOe776biyNkrI explicit
Authenticated to codeup.aliyun.com ([118.118.31.XXX.XX) using "publickey".
... ...

在Windows操作系统,Git的SSH认证使用的可能不是标准的OpenSSH命令,可通过环境变量GIT_SSH_COMMAND或者Git配置变量core.sshcommand设置使用指定的SSH命令,可能是plink.exe或者tortoiseplink.exe。验证登录的方式同上。

Git的HTTPS认证方式

使用HTTPS协议访问远程Git仓库时,通常使用HTTPS协议的基本认证(Basic Authentication)。登录时使用用户在代码平台上的登录名,以及专门为Git认证申请的令牌(Token)。为了避免频繁输入用户名和令牌的繁琐,Git提供了认证助手帮助缓存用户名和口令,因此通常只需要在第一次登录时输入用户名和令牌。

使用如下命令可以查看当前系统中所使用的认证助手:

 $ git config credential.helper
 store

示例中认证助手配置为store,Git会使用内部命令git-credential-store来缓存口令。Windows上常用的认证助手为git-credential-wincred

如何确认当前Git的HTTPS认证使用哪一个用户名进行的登录?如果通过模拟Git和认证助手的交互获取认证使用的用户名会稍显麻烦。

一个简单的确认 Git HTTP 认证使用了指定用户名的方式是:将用户名编码在URL中(切忌不要将令牌编码在 URL中)。

例如:地址https://got***@codeup.aliyun.com/my/example.git中将用户名gotgit编码在URL地址中,就可以确认操作该仓库地址时使用的一定是指定的用户名。

如果想要修改一个已经克隆出来的本地仓库的地址,可以使用 git remote命令。

  • 查看 origin 标识的远程仓库地址,使用命令:git remote get-url origin

  • 修改 origin 标识的远程仓库地址,使用命令:git remote set-url origin 。