在Go Git中,如何使用SSH代理进行身份验证?

nkoocmlb  于 2023-02-28  发布在  Git
关注(0)|答案(1)|浏览(223)

我已经在https://docs.github.com/en/authentication/connecting-to-github-with-ssh;之后使用SSH设置了Git,我已经在www.example.com之后将我的密钥添加到SSH代理https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent。我想使用go-git,并尝试了以下示例(在此注解之后):

package main

import (
    "log"
    "os"

    "github.com/go-git/go-git/v5"
    "github.com/go-git/go-git/v5/plumbing/transport/ssh"
)

func main() {
    authMethod, err := ssh.DefaultAuthBuilder("keymaster")
    if err != nil {
        log.Fatalf("default auth builder: %v", err)
    }

    if _, err := git.PlainClone("/tmp/foo", false, &git.CloneOptions{
        URL:      "git@github.com:org/repo.git",
        Progress: os.Stdout,
        Auth:     authMethod,
    }); err != nil {
        log.Fatalf("plain clone: %v", err)
    }
}

但是,当我运行它时,我得到了以下错误:

> go run main.go
2023/02/20 06:55:25 plain clone: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
exit status 1

从www.example.com上看https://github.com/go-git/go-git/blob/c35b8082c863f2106de1c3c95ba9ed21d30f9371/plumbing/transport/ssh/common.go#L37-L39,DefaultAuthBuilder似乎只是NewSSHAgentAuth的别名,但我不清楚如何提供正确的用户名来获得auth方法。有人知道如何做到这一点吗?

yeotifhr

yeotifhr1#

看起来让go-git使用代理进行身份验证的最简单方法是让它自己选择一种身份验证方法。

package main

import (
  "log"
  "os"

  "github.com/go-git/go-git/v5"
)

func main() {
  repo := os.Args[1]
  dir := os.Args[2]

  if _, err := git.PlainClone(dir, false, &git.CloneOptions{
    URL:      repo,
    Progress: os.Stdout,
  }); err != nil {
    log.Fatalf("plain clone: %v", err)
  }
}

如果我将它指向一个私有存储库(./gg git@github.com/larsks/somepriverepo myrepo),它将使用来自我的代理的密钥成功地进行身份验证,并生成存储库的本地克隆。
看起来ssh.DefaultAuthBuilderusername参数需要是远程系统上的目标用户名...在本例中是git;只要你获取的是git@...的URL,这个方法也能用:

package main

import (
  "log"
  "os"

  "github.com/go-git/go-git/v5"
  "github.com/go-git/go-git/v5/plumbing/transport/ssh"
)

func main() {
  repo := os.Args[1]
  dir := os.Args[2]

  authMethod, err := ssh.DefaultAuthBuilder("git")
  if err != nil {
    log.Fatalf("default auth builder: %v", err)
  }

  if _, err := git.PlainClone(dir, false, &git.CloneOptions{
    URL:      repo,
    Progress: os.Stdout,
    Auth:     authMethod,
  }); err != nil {
    log.Fatalf("plain clone: %v", err)
  }
}

对于更通用的解决方案,您需要从存储库URL解析用户名。

相关问题