为了账号安全,请及时绑定邮箱和手机立即绑定

使用基本身份验证的 HTTP 请求返回 401 而不是 301 重定向

使用基本身份验证的 HTTP 请求返回 401 而不是 301 重定向

Go
慕的地10843 2021-11-15 15:17:13
使用 Go 1.5.1。当我尝试向使用基本身份验证自动重定向到 HTTPS 的站点发出请求时,我希望得到 301 重定向响应,而不是 401。package mainimport "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知道可能出了什么问题吗?
查看完整描述

1 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

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


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


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


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


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


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 的功能,请直接使用传输。传输不遵循重定向。


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

应用程序还可以使用客户端CheckRedirect函数和可区分的错误来防止重定向,如如何使 Go HTTP 客户端不自动跟随重定向的答案中所示?. 这种技术似乎有点流行,但比直接使用传输更复杂。


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)

}


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 212 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信