现状
在选择了一个附带项目(围绕第三方API构建一个包装器)之后,我陷入了困境。我正在使用吊索来编写我的HTTP请求。
因此,客户端的部分组成如下:
type Client struct {
// some services etc..
sling *sling.Sling <-- this is initialized with *http.Client
}
func NewClient(httpClient *http.Client) *Client {
sling := sling.New().Client(httpClient).Base(BaseURL)
}
//....我不能把头绕在头上的东西
我遵循与github和go-推特相同的原则,即身份验证不应该由我的库来处理,而应该由Golangsoauth1/2包来处理。
由于API提供了应用程序和用户级别的身份验证,而且有些工作流需要初始的应用程序级身份验证,然后是用户级身份验证,因此我的问题是,是否有任何方法可以更改*http.Transport,以便在客户端基础上更改身份验证标头。
到目前为止,我还没有找到这样做的方法。
发布于 2017-04-17 09:26:33
如果您想要的话,http.Client有一个Transport字段,您可以使用该字段“在客户端基础上更改身份验证头”。Transport字段的类型是http.RoundTripper,它是一个方法接口,所以您所需要做的就是使用RoundTrip方法的实现来定义传输。
type MyTransport struct {
apiKey string
// keep a reference to the client's original transport
rt http.RoundTripper
}
func (t *MyTransport) RoundTrip(r *http.Request) (*http.Response, error) {
// set your auth headers here
r.Header.Set("Auth", t.apiKey)
return t.rt.RoundTrip(r)
}现在,您可以使用这种类型的实例在Transport上设置http.Client字段。
var client *http.Client = // get client from somewhere...
// set the transport to your type
client.Transport = &MyTransport{apiKey: "secret", tr: client.Transport}根据客户端的方式和位置,可能还没有设置其Transport字段,因此在这种情况下确保您的类型使用默认传输可能是个好主意。
func (t *MyTransport) transport() http.RoundTripper {
if t.rt != nil {
return t.rt
}
return http.DefaultTransport
}
// update your method accordingly
func (t *MyTransport) RoundTrip(r *http.Request) (*http.Response, error) {
// set your auth headers here
r.Header.Set("Auth", t.apiKey)
return t.transport().RoundTrip(r)
}值得注意的是,Go文档建议不要修改RoundTrip方法中的*http.Request,所以您可以做的以及链接到的github包要做的是创建请求的副本,设置其上的auth标头,并将其传递给底层Transport。见此处:https://github.com/google/go-github/blob/d23570d44313ca73dbcaadec71fc43eca4d29f8b/github/github.go#L841-L875
https://stackoverflow.com/questions/43447405
复制相似问题