文档

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

更新时间:

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

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
git@codeup.aliyun.com:my/example.git

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

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

  2. 采用 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命令。

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

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