简而言之,您的问题是,在您的urlfetch示例中,您将访问令牌嵌入到请求正文中,并且由于您发出了一个GET请求 – 它无法携带任何请求正文 – 这些信息将被丢弃.
为什么你的第一个片段有效?
因为requests.get()接受了可选的params参数,意思是:“把这个字典我给你,将它的所有键/值对转换成query string并将它附加到主URL”
所以,在窗帘后面,requests.get()正在构建一个这样的字符串:
https://api.particle.io/v1/devices?access_token=ACCESS_TOKEN
这是您应该将GET请求指向的正确端点.
你的第二个片段为什么不起作用?
这次,urlfetch.fetch()使用与requests.get()不同的语法(但仍然等效).这里需要注意的重要一点是,有效负载参数与我们之前在requests.get()中使用的params参数并不相同.
urlfetch.fetch()期望我们的查询字符串-if any-已经被urlencoded到URL中(这就是urllib.urlencode()在这里发挥作用的原因).另一方面,有效负载是您应该放置请求主体的地方,以防您发出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方法,参数和请求体,而不是我在这里的不良解释.
PS:如果particle.io服务器支持它(他们应该),你应该远离这个身份验证模式并在授权中携带你的令牌:Bearer< access_token>头而已.在URL中携带访问令牌并不是一个好主意,因为它们以这种方式更加明显并且倾向于保持登录服务器,因此存在安全风险.另一方面,在TLS会话中,所有请求标头始终都是加密的,因此您的身份验证令牌在那里很好地隐藏.