【发布时间】:2016-10-18 01:04:16
【问题描述】:
更新:已解决。除其他外,我确实犯了一个基本错误。我对session.headers.update 函数的使用不正确;而不是session.headers.update = {foo:bar},我需要做session.headers.update({foo:bar})。此外,我更改了以下代码部分:
从这里:
payload = urllib.parse.urlencode({
"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": str(token)
})
到这里:
payload = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + token.decode("utf-8")
代码现在按预期工作。
下面的原始问题
我已经在 SO 和 Google 上看到了一些关于这个问题的点击;他们都没有帮助,尽管我确实确保仔细检查我的代码以确保我没有犯他们详述的相同问题。人们往往遇到的问题涉及将 POST 数据作为参数传递或 POST 到错误的 URL,据我所知,我没有这样做。此外,我发现的大多数点击都涉及涉及用户的三足 OAuth2。我发现与服务帐户和 JWT 相关的点击次数相对较少,这与用户流程的差异很大,我担心它们与我的问题的相关性。
我正在尝试从 Google 身份验证服务器获取服务帐户的访问令牌。我已经生成了我的 JWT,现在想 POST 到服务器以接收我的访问令牌。我已经根据here 描述的文档在“发出访问令牌请求”下设置了标头,据我所知,我的请求符合规范,但 Google 以 400 响应回复,并且以下 JSON:
{'error': 'invalid_request', 'error_description': 'Required parameter is missing: grant_type'}
这是导致问题的代码:
# Returns the session, now with the Host and Authorization headers set.
def gAuthenticate(session):
token = createJWT()
session.headers.update = {
"Host": "www.googleapis.com",
"Content-Type": "application/x-www-form-urlencoded"
}
payload = urllib.parse.urlencode({
"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": str(token)
})
response = session.post("https://www.googleapis.com/oauth2/v4/token", data = payload)
session.headers.update = {"Authorization": "Bearer " + response.json()["access_token"]}
return session
这段代码有很多奇怪的问题。首先,如果我不urllib.parse.urlencode 我的字典(即简单地payload = {dictionary}),我只会得到一个Bad Request / 'invalid_request' 错误,我从不太具体的错误消息中假设这意味着这比我更不可接受我目前在做。为什么我必须这样做? Requests 不应该为我编码我的数据吗?我以前在使用 Requests 发布时从未遇到过这个问题。
其次,在发送之前检查准备好的请求会发现我的标头设置不正确,尽管标头已更新。我添加到请求中的任何一个标头都没有被传输。
我检查了请求正文,它看起来与 Google 在文档中作为示例提供的内容相同(当然 JWT 的内容除外)。
所有这些让我相信我在某个地方犯了一个非常基本的错误,但我没有成功找到它。我在这里做错了什么?任何有用的文档的链接将不胜感激;感谢您的时间和关注。
【问题讨论】:
标签: python google-api python-requests google-oauth