0

我想使用 Go 反向代理服务器保护 Docker 守护程序 REST API。我发现这篇文章非常相关。我从未使用过 Go,因此不确定如何使用静态用户名和密码对此进行基本身份验证。我尝试了我碰巧在谷歌上找到的所有可能的方法,但没有一个对我有用。

有人可以帮助将静态 basicAuth 身份验证添加到以下代码,以便请求只有在请求包含用户名和密码时才能访问 Docker 守护程序 API: https ://github.com/ben-lab/blog-material/blob/master/ golang-reverse-proxy-2/reverse-proxy.go

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "time"

    "github.com/tv42/httpunix"
)

func handleHTTP(w http.ResponseWriter, req *http.Request) {

    fmt.Printf("Requested : %s\n", req.URL.Path)

    u := &httpunix.Transport{
        DialTimeout:           100 * time.Millisecond,
        RequestTimeout:        1 * time.Second,
        ResponseHeaderTimeout: 1 * time.Second,
    }
    u.RegisterLocation("docker-socket", "/var/run/docker.sock")

    req.URL.Scheme = "http+unix"
    req.URL.Host = "docker-socket"

    resp, err := u.RoundTrip(req)

    if err != nil {
        http.Error(w, err.Error(), http.StatusServiceUnavailable)
        return
    }
    defer resp.Body.Close()
    copyHeader(w.Header(), resp.Header)
    w.WriteHeader(resp.StatusCode)
    io.Copy(w, resp.Body)
}
func copyHeader(dst, src http.Header) {
    for k, vv := range src {
        for _, v := range vv {
            dst.Add(k, v)
        }
    }
}
func main() {

    server := &http.Server{
        Addr:    ":8888",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handleHTTP(w, r) }),
    }

    log.Fatal(server.ListenAndServe())
}

https://github.com/ben-lab/blog-material/blob/master/golang-reverse-proxy-2/reverse-proxy.go

4

2 回答 2

0

您可以通过调用 BasicAuth()您的

req *http.Request object

喜欢:

user, pass, _ := req.BasicAuth()

然后将 user 和 pass 与您拥有的静态值进行比较。

https://golang.org/pkg/net/http/#Request.BasicAuth

更新:

func handleHTTP(w http.ResponseWriter, req *http.Request) {
    user, pass, _ := req.BasicAuth()
    if user != "muuser" || pass != "mysecret" {
      // you have to import "errors"
      http.Error(w, errors.New("not authoized!!"), http. StatusUnauthorized)
        return
    }
    fmt.Printf("Requested : %s\n", req.URL.Path)

    u := &httpunix.Transport{
        DialTimeout:           100 * time.Millisecond,
        RequestTimeout:        1 * time.Second,
        ResponseHeaderTimeout: 1 * time.Second,
    }
    u.RegisterLocation("docker-socket", "/var/run/docker.sock")

    req.URL.Scheme = "http+unix"
    req.URL.Host = "docker-socket"

    resp, err := u.RoundTrip(req)

    if err != nil {
        http.Error(w, err.Error(), http.StatusServiceUnavailable)
        return
    }
    defer resp.Body.Close()
    copyHeader(w.Header(), resp.Header)
    w.WriteHeader(resp.StatusCode)
    io.Copy(w, resp.Body)
}
于 2020-12-11T03:00:00.280 回答
0

在这里,您可以从我的以下小项目中复制逻辑。

https://github.com/alessiosavi/StreamingServer/blob/0f65dbfc77f667777d3047fa1a6b1a2cbd8aaf26/auth/authutils.go

首先,您需要一个服务器来存储用户(我使用过 Redis)。

比您需要3个功能的用户

  • 登录用户
  • 注册用户
  • 删除用户

在登录/注册阶段,您生成一个 cookie 散列用户名/密码并将 cookie 设置到 Redis 表中

比每次调用 API 时都要验证。

随意复制您需要的代码。

如果某些事情不能很好理解,请打开一个问题。

于 2020-12-11T00:37:55.390 回答