英文:
Fetching asna redirect url parameter on google app engine in golang
问题
我的asana oauth重定向URL类似于
https://testapp.appspot.com/api/redirect.asana#access_token=123456789
我不确定如何获取access_token。
注意: 如果我将?更改为#,那么通过使用r.FormValue("access_token")可以正常工作。
英文:
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
得分: 1
r.FormValue()
无法获取到参数的原因是因为URL参数是由?
分隔的,但在你的URL中并没有。
#
符号用于分隔引用的片段,所以你的access_token
应该在r.URL.Fragment
中...但实际上并不在那里。
无法从浏览器中测试
片段不会发送到服务器,片段是给浏览器使用的。有一个问题涵盖了这个问题:
net/http: document fields set in Request.URL in handler #3805
这也包含在http.Request
的文档中:
> 对于服务器请求,URL是从RequestURI中提供的URI解析而来的。对于大多数请求,除了Path和RawQuery之外的字段都将为空。(参见RFC 2616,第5.1.2节)
从请求中获取它的代码
如果非浏览器客户端将其作为请求路径的一部分发送,您可以使用简单的string
操作来获取令牌值:它是=
字符后面的部分。您可以使用strings.Index()
来查找"="
:
raw := r.URL.Path
if idx := strings.Index(raw, "="); idx >= 0 && idx < len(raw)-1 {
token := raw[idx+1:]
fmt.Fprintln(w, "Token:", token)
}
输出:
Token: 123456789
作为另一种解决方案,您还可以使用strings.Split()
将其拆分为"="
,第二个元素将是令牌的值:
parts := strings.Split(r.URL.Path, "=")
fmt.Fprintln(w, "Parts:", parts)
if len(parts) == 2 {
fmt.Fprintln(w, "Token:", parts[1])
}
输出:
[/api/redirect.asana#access_token 123456789]
Token: 123456789
测试代码
这是一个使用net/http
调用您的服务器的代码,它将发送一个路径为"/api/redirect.asana#access_token=123456789"
的请求,并将响应正文打印到标准输出(控制台):
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)
英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论