Fetching asna redirect url parameter on google app engine in golang

147 views Asked by At

My asana oauth redirect URL is something like

https://testapp.appspot.com/api/redirect.asana#access_token=123456789

I am not sure how to fetch access_token now.

Note : if I am changing ? to # then its working fine by using r.FormValue("access_token").

1

There are 1 answers

8
icza On

The reason why r.FormValue() does not get it is because URL parameters are separated by ? but in your URL it is not.

The # is used to separate a fragment for references, so your access_token should be in r.URL.Fragment... but it won't.

You can't test it from the browser

Fragments are not sent over to the server, fragments are for the browsers. There was an issue covering this:

net/http: document fields set in Request.URL in handler #3805

It is also included in the doc of http.Request:

For server requests the URL is parsed from the URI supplied on the Request-Line as stored in RequestURI. For most requests, fields other than Path and RawQuery will be empty. (See RFC 2616, Section 5.1.2)

Code to get it from the request

If a non-browser client does send it as part of the request path, you can use simple string operations to get the token value: it is the part after the = character. You can use strings.Index() to find the "=":

raw := r.URL.Path
if idx := strings.Index(raw, "="); idx >= 0 && idx < len(raw)-1 {
    token := raw[idx+1:]
    fmt.Fprintln(w, "Token:", token)
}

Output:

Token: 123456789

As an alternative solution you can also use strings.Split() to split it by "=", 2nd element will be the value of the token:

parts := strings.Split(r.URL.Path, "=")
fmt.Fprintln(w, "Parts:", parts)
if len(parts) == 2 {
    fmt.Fprintln(w, "Token:", parts[1])
}

Output:

[/api/redirect.asana#access_token 123456789]
Token: 123456789

Code to test it

Here is a code using net/http to call your server that will send a path being "/api/redirect.asana#access_token=123456789", and it will print the response body to the standard output (console):

c := &http.Client{}
req, err := http.NewRequest("GET", "http://localhost:8080/", nil)
if err != nil {
    panic(err)
}
req.URL.Path = "/api/redirect.asana#access_token=123456789"
resp, err := c.Do(req)
if err != nil {
    panic(err)
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)