【问题标题】:Go HTTP Request with Basic Auth returning a 401 instead of a 301 redirectGo HTTP Request with Basic Auth 返回 401 而不是 301 重定向
【发布时间】:2015-12-21 10:47:19
【问题描述】:

使用 Go 1.5.1。

当我尝试向使用基本身份验证自动重定向到 HTTPS 的站点发出请求时,我希望得到 301 重定向响应,而不是 401。

package main

import "net/http"
import "log"

func main() {
    url := "http://aerolith.org/files"
    username := "cesar"
    password := "password"
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        log.Println("error", err)
    }
    if username != "" || password != "" {
        req.SetBasicAuth(username, password)
        log.Println("[DEBUG] Set basic auth to", username, password)
    }
    cli := &http.Client{

    }
    resp, err := cli.Do(req)
    if err != nil {
        log.Println("Do error", err)
    }
    log.Println("[DEBUG] resp.Header", resp.Header)
    log.Println("[DEBUG] req.Header", req.Header)
    log.Println("[DEBUG] code", resp.StatusCode)

}

注意 curl 返回 301:

curl -vvv http://aerolith.org/files --user cesar:password

知道可能出了什么问题吗?

【问题讨论】:

    标签: redirect curl go


    【解决方案1】:

    http://aerolith.org/files 的请求重定向到https://aerolith.org/files(注意从http 更改为https)。对https://aerolith.org/files 的请求重定向到https://aerolith.org/files/(注意添加尾随/)。

    Curl 不遵循重定向。 Curl 打印从 http://aerolith.org/fileshttps://aerolith.org/files/ 的重定向的 301 状态。

    Go 客户端遵循两个重定向到https://aerolith.org/files/。对 https://aerolith.org/files/ 的请求返回状态 401,因为 Go 客户端没有通过重定向传播授权标头。

    Go 客户端对https://aerolith.org/files/ 的请求,Curl 返回状态 200。

    如果您想成功跟踪重定向和身份验证,请在 CheckRedirect 函数中设置身份验证标头:

    cli := &http.Client{
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            if len(via) >= 10 {
                return errors.New("stopped after 10 redirects")
            }
            req.SetBasicAuth(username, password)
            return nil
        }}
    resp, err := cli.Do(req)
    

    如果您想匹配 Curl 的功能,请直接使用 transport。传输不遵循重定向。

    resp, err := http.DefaultTransport.RoundTrip(req)
    

    应用程序还可以使用客户端 CheckRedirect 函数和一个显着错误来防止重定向,如对 How Can I Make the Go HTTP Client NOT Follow Redirects Automatically? 的回答所示。这种技术似乎有点流行,但比直接使用传输更复杂。

    redirectAttemptedError := errors.New("redirect")
    cli := &http.Client{
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return redirectAttemptedError
        }}
    resp, err := cli.Do(req)
    if urlError, ok := err.(*url.Error); ok && urlError.Err == redirectAttemptedError {
        // ignore error from check redirect
        err = nil   
    }
    if err != nil {
        log.Println("Do error", err)
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-09
      • 2018-07-23
      • 1970-01-01
      • 2012-02-04
      • 2013-09-10
      • 1970-01-01
      • 2015-11-11
      • 2019-04-12
      • 2013-02-12
      相关资源
      最近更新 更多