我正在尝试在google应用引擎应用中向python中的粒子服务器发出请求。
在我的终端中,我可以简单而成功地完成请求,请求为:
res = requests.get('https://api.particle.io/v1/devices', params={"access_token": {ACCESS_TOKEN}})
但在我的应用程序中,同样的事情不适用于urlfetch,它一直告诉我它无法找到访问令牌:
url = 'https://api.particle.io/v1/devices'
payload = {"access_token": {ACCESS_TOKEN}}
form_data = urllib.urlencode(payload)
res = urlfetch.fetch(
url=url,
payload=form_data,
method=urlfetch.GET,
headers={
'Content-Type':
'application/x-www-form-urlencoded'
},
follow_redirects=False
)
我不知道问题是什么,也没办法调试。谢谢!
答案 0 :(得分:10)
简而言之,您的问题是,在您的urlfetch
示例中,您将访问令牌嵌入到请求正文中,并且因为您发出了GET请求 - 它无法携带任何请求身体与他们 - 这些信息被丢弃。
为什么您的第一个代码段有效?
因为requests.get()
采用了可选的params
参数,这意味着:"拿这个我给你的字典,将其所有的键/值对转换为query string并将其附加到主要网址"
所以,在幕后,requests.get()
正在构建一个这样的字符串:
https://api.particle.io/v1/devices?access_token=ACCESS_TOKEN
您应该将GET请求指向正确的端点。
为什么您的第二个代码段不起作用?
这一次,urlfetch.fetch()
使用的语法与requests.get()
不同(但仍然相同)。这里需要注意的重要一点是,payload
参数不会与您之前在params
中使用的requests.get()
参数相同。
urlfetch.fetch()
期望我们的查询字符串-if any-已经被urlencoded到URL中(这就是urllib.urlencode()
在这里发挥作用的原因)。另一方面,payload
是你应该放置请求主体的地方,以防你发出POST,PUT或PATCH请求,但是particle.io的端点不期望你的OAuth访问令牌在那里
这样的事情应该有效(免责声明:未经测试):
auth = {"access_token": {ACCESS_TOKEN}}
url_params = urllib.urlencode(auth)
url = 'https://api.particle.io/v1/devices?%s' % url_params
res = urlfetch.fetch(
url=url,
method=urlfetch.GET,
follow_redirects=False
)
请注意,现在我们不再需要您之前的Content-type
标题了,因为我们毕竟不会携带任何内容。因此,可以从此示例调用中删除headers
参数。
如需进一步参考,请查看urlfetch.fetch()
reference和this SO thread,希望能让您更好地了解HTTP方法,参数和请求正文,而不是我在这里的不良解释。< / p>
PS:如果particle.io服务器支持它(它们应该),您应该远离此身份验证架构,而是将您的令牌放在Authorization: Bearer <access_token>
标头中。在URL中携带访问令牌并不是一个好主意,因为它们以这种方式更加明显并且倾向于保持登录服务器,因此存在安全风险。另一方面,在TLS会话中,所有请求标头始终都是加密的,因此您的身份验证令牌会被隐藏在那里。
答案 1 :(得分:0)
好的,事实证明,使用Urlfetch的GET请求不能包含有效负载。相反,必须使用'?'在url中包含参数语法如下:
url = 'https://api.particle.io/v1/devices'
url = url + '?access_token=' + {ACCESS_TOKEN}
res = urlfetch.fetch(
url=url,
method=urlfetch.GET,
follow_redirects=False
)
这对我有用。