简体   繁体   English

在Go中添加默认的HTTP标头

[英]Adding a default HTTP header in Go

I'm taking my first steps in Go and would like to consume a REST API. 我正在Go中迈出第一步,并且想使用REST API。 The server requires each request to be authorized with a bearer token. 服务器要求使用承载令牌来授权每个请求。

How can I add this header to the client so that every request uses this token? 如何将此标头添加到客户端,以便每个请求都使用此令牌?

import "net/http"

const accessToken = "MY_DEMO_TOKEN"

func main() {
    customHeader := http.Header{}
    customHeader.Add("Authorization: Bearer %s", accessToken)
    client := &http.Client{
        Timeout: time.Second*10,
    }
}

You can decorate the client's Transport. 您可以装饰客户的运输工具。 For instance: 例如:

package main

import "net/http"

func main() {
        client := http.DefaultClient

        rt := WithHeader(client.Transport)
        rt.Set("Authorization", "Bearer <token>")
        client.Transport = rt

        client.Get("http://example.com")
}

type withHeader struct {
        http.Header
        rt http.RoundTripper
}

func WithHeader(rt http.RoundTripper) withHeader {
        if rt == nil {
                rt = http.DefaultTransport
        }

        return withHeader{Header: make(http.Header), rt: rt}
}

func (h withHeader) RoundTrip(req *http.Request) (*http.Response, error) {
        for k, v := range h.Header {
                req.Header[k] = v
        }

        return h.rt.RoundTrip(req)
}

For the specific purpose of authorization tokens, you might be interested in the golang.org/x/oauth2 package, which does essentially the same, but also supports automatic token renewal: 对于授权令牌的特定目的,您可能对golang.org/x/oauth2软件包感兴趣,该软件包本质上是相同的,但是还支持自动令牌更新:

package main

import (
        "context"

        "golang.org/x/oauth2"
)

func main() {
        ctx := context.Background()
        client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{
                AccessToken: "<your token>",
                TokenType:   "Bearer",
        }))

        client.Get("http://example.com")
}

You can write a decorator around http.RoundTripper and pass it to the client. 您可以围绕http.RoundTripper编写装饰器,并将其传递给客户端。 But practically I would end up with a helper that prepares request for each query as was suggested by Adrian. 但是实际上,我最终会得到一个助手,该助手会按照Adrian的建议为每个查询准备请求。

package main

import (
    "fmt"
    "net/http"
    "time"
)

const accessToken = "MY_DEMO_TOKEN"

type MyRoundTripper struct {
    r http.RoundTripper
}

func (mrt MyRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
    r.Header.Add("Authorization", "Bearer: "+accessToken)
    return mrt.r.RoundTrip(r)
}

func main() {
    client := &http.Client{
        Timeout:   time.Second * 10,
        Transport: MyRoundTripper{r: http.DefaultTransport},
    }

    fmt.Println(client.Get("http://google.com/"))
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM