【问题标题】:Adding basic authentication to Go based reverse proxy server向基于 Go 的反向代理服务器添加基本身份验证
【发布时间】:2020-12-10 21:16:42
【问题描述】:

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

是否可以帮助将静态 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

【问题讨论】:

    标签: go reverse-proxy basic-authentication docker-daemon


    【解决方案1】:

    您可以通过调用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)
    }
    

    【讨论】:

    • 您能否分享如何从 re *http.Request 对象调用 BasicAuth,因为我尝试查看 google 上的一些示例代码但无法使其工作。提前致谢
    • 更新了我的答案以显示如何在您的代码中执行此操作。请不要你必须导入“错误”
    • 导入了“错误”但由于以下错误而无法构建:reverse-proxy.go:17:31: cannot use errors.New("not authoized!!") (type error) as type http.Error 参数中的字符串
    • 效果很好,非常感谢朋友的帮助。只需要更改:http.Error(w, errors.New("not authoized!!"), http.StatusUnauthorized) 到 http.Error(w, errors.New("not authoized!!").Error(), http.StatusUnauthorized)
    • 需要更多帮助,您能否指导我如何使用 docker 客户端进行连接?它适用于 curl,但不适用于 docker 客户端。我使用 docker login 尝试过,但我认为收到未经授权的 401 错误。你能帮我解决这个问题吗?就像我如何向此命令添加凭据? docker -H=127.0.0.1:8888 容器ls
    【解决方案2】:

    给你,你可以从我下面的小项目中复制逻辑。

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

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

    比你需要为用户提供 3 个功能

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

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

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

    随意复制您需要的代码。

    如果有什么不好理解的,请打开一个问题。

    【讨论】:

    • 太棒了,谢谢,我一定会试试这个。我对golang不是很精通,请您分享一个可以使用硬编码用户名和密码的功能。我不需要用户注册和删除功能,只需要保护密码。非常感谢您的帮助。
    猜你喜欢
    • 2011-06-28
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 2013-01-24
    • 2020-05-26
    相关资源
    最近更新 更多