【问题标题】:Golang reverse proxy with custom authentication具有自定义身份验证的 Golang 反向代理
【发布时间】:2017-07-27 19:35:51
【问题描述】:

在将请求代理到远程服务器之前,我正在尝试通过调用 REST api 来验证用户身份。 但是,我发现如果我在代理到远程服务器之前进行 api 调用,请求将失败并出现以下错误:

http: proxy error: http: ContentLength=139 with Body length 0.

如果我在代理到远程服务器之前删除 api 调用,请求可以通过并返回正确的响应。

我的中间件如下:

func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                // the api call to external auth server
        user_id, err := authenticate(r.FormValue("username"), r.FormValue("password"))      
                if err != nil {
            http.Error(w, err.Error(), 401)
            return
        }
        next.ServeHTTP(w, r)
    })
}

我的反向代理如下:

func NewReverseProxy(target *url.URL) *httputil.ReverseProxy {
    director := func(req *http.Request) {
        req.URL.Scheme = target.Scheme
        req.URL.Host = target.Host
        req.URL.Path = target.Path
        targetQuery := target.RawQuery
        if targetQuery == "" || req.URL.RawQuery == "" {
            req.URL.RawQuery = targetQuery + req.URL.RawQuery
        } else {
            req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
        }
        if _, ok := req.Header["User-Agent"]; !ok {
            // explicitly disable User-Agent so it's not set to default value
            req.Header.Set("User-Agent", "")
        }
    }
    return &httputil.ReverseProxy{Director: director}
}

我正在使用 Chi 进行路由

r.Use(AuthMiddleware)
r.Post("/", NewReverseProxy(targets).ServeHTTP)

这个实现有什么问题?

【问题讨论】:

标签: authentication go reverse-proxy middleware


【解决方案1】:

如果您不再关心正文,您可以将请求的 contentlength 设置为 0,反映正文的当前状态:

func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // the api call to external auth server
        user_id, err := authenticate(r.FormValue("username"), r.FormValue("password"))
        if err != nil {
            http.Error(w, err.Error(), 401)
            return
        }
        r.ContentLength = 0
        next.ServeHTTP(w, r)
    })
}

【讨论】:

  • 当使用r.ContentLength = 0时,是否意味着body会通过代理而不做任何修改?和r.ContentLength = -1 有什么区别?
猜你喜欢
  • 2011-06-28
  • 2010-09-16
  • 2012-09-22
  • 2014-02-12
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
相关资源
最近更新 更多