更新:已解决。除了其他事情,我确实犯了一个基本错误。我对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'
错误,我从错误消息中得出的错误意味着这是比我目前所做的更不可接受。为什么我要这样做?不是请求应该为我编码我的数据吗?我之前在使用请求进行POST时从未遇到过这个问题。
其次,在发送之前检查准备好的请求会显示我的标题未正确设置,尽管标题更新。我添加到请求中的标头都没有被传输。
我已经检查了请求正文,它看起来与Google在文档中提供的示例相同(当然除了JWT的内容)。
所有这些让我相信我在某个地方犯了一个非常基本的错误,但我没有找到任何成功。我在这做错了什么?任何有用的文件的链接将非常感谢;感谢您的时间和关注。
答案 0 :(得分:0)
尝试" grant_type":" authorization_code"。并将grant type添加为标题。
另外,请检查此链接 - Accessing Google oAuth giving invalid grant_type (Bad request)