user2562301
user2562301

Reputation: 121

GOLANG HTTP Basic-Auth with Google App Engine URLFetch

How can I add an Authorization header to urlfetch client with Go?

There is a similar question answered for java and python, but not Go.

Upvotes: 0

Views: 1920

Answers (2)

Good Lux
Good Lux

Reputation: 983

I'm new to Go, please excuse this code for being ugly/malformed/just plain wrong.

I've been working my way though this and ran across the same problem on appengine.

@Caleb's answer above was a big help. I've just added some detail to that to help someone who might come across a similar problem.

Here's what my import statement looks like:

Import {
    "appengine"
    "appengine/urlfetch"
    "bytes"
    "encoding/json"
    "fmt"
    "golang.org/x/oauth2"
    "io/ioutil"
    "net/http"
    "net/url"
}

This is a function that receives and incoming authentication callback request, then replies with a request for an access token from the authentication server. In this case, fitbit, which needs an Authentication header set to "Basic" with some extra information. I couldn't figure out how to do this with the stock Oauth2 library, which doesn't seem to easily allow changing the request headers.

As you can see we the context of the incoming request (r). From that context, we get the http.Client from urlfetch.

Then we pack up and send a request back, with some authorization information.

After we get a response we print the results to the browser.

Hope this helps!

func authCallbackHandler(w http.ResponseWriter, r *http.Request) {

    data := url.Values{}
    data.Set("client_id", "231343")
    data.Add("grant_type", "authorization_code")
    data.Add("redirect_uri", "http://localhost:8080/callmebacklaterok")
    data.Add("code", "authcode123132")

    encodedData := data.Encode()

    c := appengine.NewContext(r)
    client := urlfetch.Client(c)

    urlStr := "https://api.fitbit.com/oauth2/token"
    req, _ := http.NewRequest("POST", urlStr,bytes.NewBufferString(encodedData))
    req.Header.Add("Authorization", "Basic RmFuY3kgbWVldGluZyB5b3UgaGVyZSEg")
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    fmt.Fprint(w, resp)

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
       panic(err.Error())
    }

    var bodydata interface{} 
    err = json.Unmarshal(body, &bodydata)
    if err != nil {
        panic(err.Error())
    }
    fmt.Fprint(w, bodydata)

}

Upvotes: 2

Caleb
Caleb

Reputation: 9458

urlfetch.Client(ctx) returns an HTTP client (http://godoc.org/google.golang.org/appengine/urlfetch#Client)

The http.Client has methods for Get, Post, etc... It also has Do which you can hand an arbitrary request. Create a request using http.NewRequest:

req, err := http.NewRequest("GET", "http://www.google.com", nil)

Then you can add a header like this:

req.Header.Set("Authorization", "whatever")

And call Do:

res, err := client.Do(req)

Upvotes: 2

Related Questions