Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go相当于Python';使用相同的基本身份验证发出多个请求的会话?_Go_Basic Authentication_Go Http - Fatal编程技术网

Go相当于Python';使用相同的基本身份验证发出多个请求的会话?

Go相当于Python';使用相同的基本身份验证发出多个请求的会话?,go,basic-authentication,go-http,Go,Basic Authentication,Go Http,考虑在Go with basic authentication中发出HTTP请求的示例: package main import ( "encoding/base64" "fmt" "io/ioutil" "net/http" "net/http/httptest" "strings" ) var userName = "myUserName" var password = "myPassword" func main() { ts

考虑在Go with basic authentication中发出HTTP请求的示例:

package main

import (
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/http/httptest"
    "strings"
)

var userName = "myUserName"
var password = "myPassword"

func main() {
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !checkAuth(w, r) {
            http.Error(w, "You're not authorized!", http.StatusUnauthorized)
            return
        }
        w.Write([]byte("You're authorized!"))
    }))
    defer ts.Close()

    req, err := http.NewRequest("GET", ts.URL, nil)
    check(err)

    req.SetBasicAuth(userName, password+"foo")

    resp, err := http.DefaultClient.Do(req)
    check(err)
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    check(err)

    fmt.Println(string(body))
}

// checkAuth checks authentication (cf. https://stackoverflow.com/questions/21936332/idiomatic-way-of-requiring-http-basic-auth-in-go/21937924#21937924)
func checkAuth(w http.ResponseWriter, r *http.Request) bool {
    s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
    if len(s) != 2 {
        return false
    }

    b, err := base64.StdEncoding.DecodeString(s[1])
    if err != nil {
        return false
    }

    pair := strings.SplitN(string(b), ":", 2)
    if len(pair) != 2 {
        return false
    }

    return pair[0] == userName && pair[1] == password
}

func check(err error) {
    if err != nil {
        panic(err)
    }
}
请注意,
SetBasicAuth
是一个
*http.Request
的方法,因此如果我想发出许多请求,我必须在每次请求时调用此方法

在Python中,您可以定义一个
requests.Session
,如本例所示(从):

s=requests.Session()
s、 auth=('user','pass')
s、 headers.update({'x-test':'true'})
#同时发送“x-test”和“x-test2”
s、 得到('https://httpbin.org/headers,标头={'x-test2':'true'})
是否有一种惯用的方法来定义Go中的
requests.Session
等价物(最好使用标准库)?我所能想到的就是用自己的
Do()
方法定义一个自定义客户端结构:

type MyClient struct {
    UserName, Password string
}

func (client *MyClient) Do(req *http.Request) (*http.Response, error) {
    req.SetBasicAuth(client.UserName, client.Password)
    return http.DefaultClient.Do(req)
}
在上面的脚本中调用它,就像

client := MyClient{UserName: userName, Password: password}

resp, err := client.Do(req)

这是一种避免多次调用
SetBasicAuth()
的惯用方法吗?

不能说它是否惯用,但它是有效的。我有完全相同的场景,有一个类似的解决方案,但是使用了头映射,因为我传递了内容类型、承载令牌等,这个东西被称为会话而不是客户端。