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)