如何使用用户名提供`git clone`命令

3
我正在尝试克隆一个仓库,假设URL是example.com/my-code,我的用户名是john@foo。现在的问题是,当我执行以下操作时:
$> git clone example.com/my-code
 john@example.com's password: 

这是一个错误的用户名!

我试图在URL中提供用户名。

$> git clone john@foo@example.com/my-code
john@foo@example.com's password:

即使我使用-v选项,它仍会直接要求输入密码。所以,我的问题是,我该如何提供不同的用户名?通过URL也可以,但我更喜欢使用CLI。谢谢。

但假定这确实是远程站点存储库所有者的用户名。 - matt
1
"john" 是您的本地用户名,用作显式用户名的替代。您使用什么协议连接到远程主机?这将决定您如何进行身份验证(或者是否需要进行身份验证)。 - chepner
就是这样,它是 ssh 的问题。我把它改成了 https,然后它就能工作了(可能是因为我有个个人访问令牌)。但是这使我想知道,我该怎么解决 ssh 的问题呢? - Jeanluca Scaljeri
2个回答

1

简述

您需要设置ssh配置。请参见以下内容。

详细说明

通常情况下,URL(或更准确地说是URI)的语法如下:

<scheme>:[//<authority>]<path>[?query][#fragment]

更详细的描述可以在维基百科上找到。使用ssh URL时,schemessh,冒号:和双斜杠//后面跟着user@host和另一个斜杠:

ssh://user@github.com/user/repo.git

例如。这样可以避免交互的必要性:用户名在命令中直接提供。由于ssh使用公钥加密,因此不需要密码,虽然在某些设置中可能需要提供密码短语以访问私钥。这意味着ssh可以在没有人类交互的情况下工作,这对于自动化计算机更新非常重要。(我们将在下面更详细地讨论这个问题。)
另一方面,要使用HTTPS URL,通常会编写以下内容:
https://github.com/user/repo.git

因为HTTPS身份验证通常是交互式的。因此,这里假设系统可以弹出某种身份验证交互器,用户在其中输入用户名和令牌或密码。

无论哪种情况,URI都可以容纳用户名(甚至是明文密码),但预期的使用情况不同:ssh不需要具有手和眼睛的用户,而http(s)需要。因此,它们的默认值不同。

值得注意的是,Git本身并不通过将认证部分推到另一个程序(ssh)或库(libcurl)以及用于https的单独凭据助手(外部程序)来进行身份验证,从而使其自己变得更加干净。通过这样做,它将细节留给操作系统处理,因为ssh、libcurl和各种凭据助手都针对每个操作系统进行了定制。

Git有自己特殊的伪URL语法:

[user@]host:path

是以下缩写:

ssh://[user@]host/path

这与命令行ssh如何处理可选用户和主机部分相匹配。

您可以通过选择适当的(针对您的操作系统)凭据助手来自动化https的某些或所有内容。由于它们在不同的操作系统上差异很大,因此很复杂。如果仅考虑ssh,那么它会更简单,因为它花费的时间较短,没有分散到不同的操作系统上(即使在这种情况下,它也可能变得复杂)。

如何使用ssh自动化所有或几乎所有事情

至少需要了解ssh的工作原理,至少要了解高级别的内容。(除非出现问题,否则您不需要知道密钥交换操作的所有细节。)ssh系统“希望”是安全的,这意味着不仅要向GitHub保证您确实是您本人,而且还要向您保证您连接到的计算机(认为它是GitHub)确实是GitHub。

后者通过一种常被缩写为TOFU的系统运作,即首次使用时信任。这与HTTPS/SSL截然不同(并且更简单),因为HTTPS/SSL使用认证机构和信任链,而不是TOFU:第一次您让计算机调用GitHub的计算机时,GitHub的计算机会向您的计算机提供一个秘密。您的计算机会说:“嗯,这是我第一次看到这个。您是否想信任他们是他们所说的人?”具体来说:
The authenticity of host ... can't be established. ...
Are you sure you want to continue connecting (yes/no)?

如果你回答“是”,ssh默认会记录密码,下一次当你再次访问相同的主机并提供相同的密码时,它会认为你正在访问同一个主机。这在实践中非常有效。(你可以调整此设置,但通常最好让它自动处理。)
假设你已经确认github.com是他们所声称的人,而不是由于某些奇怪的故障而被篡改成了usurper.evil,那么你的ssh现在告诉他们的ssh,你想以某个用户名登录到他们的主机。这就是Git变得有点奇怪的地方,因为大多数托管服务器让“全世界的每个人”都使用用户git登录。
为了实现这一点,您可以每次设置URL时编写git@host,例如ssh://git@github.com/user/repo.git,或者您可以使用您的ssh配置文件——在~/.ssh/config$HOME/.ssh/config或类似位置找到,具体取决于您的操作系统和shell——将git@设置为该主机或某些主机的默认值。这样,如果您不提供用户名——例如只输入ssh github.com——您的ssh将提供用户名git。要做到这一点,您需要编写:
Host github.com
    User git

在你的.ssh/config中。

但是,如果你声称在github.com上是用户git,那么github.com怎么知道你真正的身份呢?这就是公钥和私钥的作用。

值得一提的是,ssh并不一定需要在此处使用公钥。你可以使用“键盘交互”方法登录到某个主机。在这里,你提供正确的用户名在user@host部分,然后他们要求你的ssh提供密码。你的ssh从你那里读取密码,使用会话密钥加密它,以使其不以明文形式发送,然后他们使用该密钥解密它并尝试它。但是对于Git与GitHub的使用,我们从一开始就不使用此方法。

要使用公钥/私钥对,您需要在尝试使用ssh与GitHub通信之前运行ssh-keygen。 ssh-keygen程序有许多可选参数,这些参数因您的ssh版本和操作系统而异,请查阅相应的文档以获取详细信息。 ssh-keygen的输出是其中之一:有一个可以提供给任何人的公钥,以及一个保持私密的私钥。
您的公钥将进入一个文件,该文件的名称以.pub结尾,例如,如果您将特定的GitHub密钥存储在文件中,则为~/.ssh/id_rsa.github.pub(就像我一样)。 这个文件中有一行相当长的内容,它将以ssh-rsaecdsa-sha2-something开头,通常以您告诉ssh-keygen放在其中的电子邮件地址结束(但此电子邮件地址仅供参考)。

你的私钥放在另一个文件中,文件名与没有.pub结尾的文件名相同。这个文件要长得多,由许多较短的行组成,例如,如果是RSA密钥,则以-----BEGIN RSA PRIVATE KEY-----开头。这个密钥只有你自己知道:它是秘密的。

现在,你通过GitHub的网页和Web浏览器使用你的GitHub帐户和密码(而不是ssh的任何公钥/私钥)登录GitHub,并导航到存储ssh密钥的页面。然后,在此处输入你的公钥。请参见GitHub文档中的此处此处;请注意,GitHub会进行一些神奇的浏览器检测,试图为你提供特定于操作系统的指示,但并不总是有效,因此有时你可能需要单击Mac / Windows / Linux选择器,以获取你打算使用的操作系统的说明,而不是你正在浏览的操作系统的说明。

要声明在GitHub上的身份,你需要将之前存储在GitHub上的公钥发送到GitHub,以证明这是你的身份。由于公钥非常庞大且独一无二,GitHub可以通过查看谁先前提供了这个特定的公钥来确定你的身份。但由于这是一个公钥,GitHub还不能完全信任你所声称的身份。因此,GitHub会生成一组随机字节作为秘密,并使用公钥对其进行加密后发送给你。
如果你能轻松解密这些字节,那就意味着你拥有相应的私钥。没有私钥,至少理论上而言,解密将需要多年的计算时间。因此,如果你的计算机可以将字节返回给GitHub,那么你就是你自己,拥有与你发送的公钥相对应的私钥。
这就是GitHub如何知道你是谁。你是你自己,因为:
  • 你向他们提供了公钥,声称你是Jeanluca(或其他人),并且
  • 你正确地解密了他们发送的字节作为回复,表明你也拥有相应的私钥

你拥有密钥对的两个部分:当你发送公共部分时,你就是之前所声称的那个人。你只需发送公共部分即可作出这一声明:GitHub忽略(嗯... 实际上忽略)git@github.com中的git@部分(但你仍然需要发送它)。

在复杂情况下使其工作

有些人需要以两个或更多不同的身份验证到单个Web托管系统(如GitHub)。例如,拥有“工作ID”——公司身份,并且想要使用工作ID访问与工作相关的存储库,同时使用个人ID访问个人存储库,这是非常普遍的。

有一种使用ssh的“虚拟主机名”约定的简单方法来实现这一点。您仍然像往常一样生成普通的密钥对,但是您让ssh-keygen将它们保存在具有易于区分名称的文件中,例如:

.ssh/id_rsa.github.work   .ssh/id_rsa.github.work.pub
.ssh/id_rsa.github.play   .ssh/id_rsa.github.play.pub

你需要在GitHub上安装两个公钥,分别对应工作和娱乐的“你”。现在你需要让ssh提供正确的密钥。Ssh有能力尝试多个密钥,这是一种处理方法,但并不是最好的方法,因为这意味着你可能会意外使用错误的密钥对,这通常会在安全日志中显示,并引起安全人员的警报。(GitHub的运营商可能不会介意,但如果你在公司服务器上使用同样的技术,他们可能会介意。)你还可能触发攻击防御软件:如果你拿着一百万个密钥来到一个服务器,然后开始尝试所有的密钥,服务器软件可能会决定你不好,将你转移到一个假系统上,让你忙碌而试图追踪你。因此,理想情况下,你应该让ssh提供正确的密钥,这可以很容易地实现!在你的.ssh/config文件中,你可以列出:
Host gh-work
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_rsa.github.work.pub
    IdentitiesOnly yes

Host gh-play
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_rsa.github.play.pub
    IdentitiesOnly yes

例如。在这里,您告诉ssh如果运行ssh gh-work,ssh应连接到github.com,尝试作为用户git登录,并仅提供~.ssh/id_rsa.github.work.pub中的身份验证。(根据您的ssh设置和其他项目,您可能需要在此处列出私钥文件而不是公钥文件。首先尝试公钥文件。)同样,如果运行ssh gh-play,ssh应像以前一样连接到github.com,但这次使用“play”身份。

现在,您只需要使用伪造的URL配置您的Git存储库:

git clone ssh://gh-play/me/myrepo.git

要克隆您的“play user”存储库,并且:
git clone ssh://gh-work/corp/corprepo.git

要克隆一些企业“工作”存储库。存储库的URL控制你声称的身份,你声称的身份控制你是否有访问权限。一旦你克隆了存储库,你就拥有了所需的URL,它以名称“origin”存储,从此一切都可以正常运行。

请注意,在使用ssh-keygen时,必须使用真实主机名(在本例中为github.com),而不是假名如gh-work或gh-play。ssh-keygen代码不读取.ssh/config文件,并不知道gh-work代表github.com。

测试所有这些

运行:

ssh -Tv git@github.com

或者:

ssh -Tv gh-play

例如,将测试过程的ssh部分。这里不涉及Git。 -v选项告诉ssh打印详细的调试信息,以便您可以观察密钥是否传输到GitHub(或其他地方)。这个初始测试还记录了主机指纹在您的~/.ssh/known_hosts文件中,以便Git进行的未来连接不会问您是否信任GitHub。 -T选项(也包括-v选项)并不是必需的:它只是告诉您的ssh不需要尝试使用伪终端,这将避免某些错误消息。如果一切顺利,GitHub将打印以下形式的消息:
Hi _______! You've successfully authenticated, but ...

(填入空白并完善...)。 填好的空白显示了您的ssh密钥对成功声明的GitHub账户

如果事情进行得不顺利,在这里,-v的调试输出可以帮助找出原因。请注意,它非常长; 如果它不够长或详细,请使用-vv-vvv使其更长更详细。

摘要

要使用与GitHub或类似服务的ssh:

  • 配置您的ssh。
  • 生成一个或多个密钥对,并将公共密钥存储在GitHub或类似网站上,如有必要,进一步配置您的ssh。
  • 使用ssh -Tv git@github.com或类似命令进行测试。不同的托管网站有不同的方式告诉您是否成功;大多数网站都会有某种方式告诉您。
  • 现在尝试使用包含您选择用于访问托管站点的主机名的ssh URL(s)和您设置的ssh ID(s)来克隆git clone。请记住,您只能克隆现有存储库;如果您需要在托管网站上创建新的存储库,则通常必须通过其Web界面进行操作。
请务必使用ssh URL。这些URL以ssh://开头,或者您可以使用user@host:path/to/repo.git语法,但这只是为了让您少输入六个字母;比较ssh://github.com/me/repo.git(28个字母)和github.com:me/repo.git(22个字母)。一旦您输入了URL,之后就只需使用origin(六个字母)即可。

1

john@ 或者 git@?

为什么要使用 john@foo@?在这种情况下应该只使用 john@ 或者 foo@

否则使用 git@,它是 GitHub 和 GitLab 的常用用户名。它将使用您的 SSH 凭据。 如果您拥有 GitHub 或 GitLab 仓库,则可以在那里查看 SSH URL。您不必更改用户名。

通过SSH克隆代码URL

确保将您的公钥添加到个人资料设置中!
如果您正在讨论用户名/电子邮件,请阅读下面的内容。

全局配置用户和电子邮件地址

要全局配置您的用户和/或电子邮件地址,请使用以下命令:

$ git config --global user.name "Example Name"
$ git config --global user.email "en@example.com"

配置当前仓库的用户和电子邮件

要为当前仓库设置用户和电子邮件,您可以执行与上面相同的操作,但是删除--global标志。

$ git config user.name "Example Name"
$ git config user.email "en@example.com"

一次性配置用户和电子邮件

如果您只想为一次调用更改特定用户和/或电子邮件地址,则可以更改配置:

$ git -c user.name="Example Name" -c user.email="en@example.com"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接