Python OAuth错误"无效授权"

时间:2015-01-21 19:12:50

标签: python oauth http-status-code-400 service-accounts

我在一家小公司工作,该公司的邮件通过Google托管。作为负责管理员工帐户的管理员之一,我尝试使用Google API和一个或多个专用服务帐户自动执行某些任务。我在下面编写了简短的Python脚本,根据Google提供的文档请求访问令牌,但我仍然收到“invalid_grant”错误。

我做了以下事情:

  • 以服务帐户登录Google Developers Console并创建项目
  • 创建了服务帐户类型的客户端ID
  • 登录Google管理控制台并添加了我希望该帐户可以访问的客户电子邮件地址和范围网址

在线搜索已得出答案,表明机器的系统时间已关闭,已超出刷新令牌的限制或已使用客户端ID而非客户端电子邮件。我在运行脚本之前在Windows机器和Linux机器上同步了时间,并出现相同的错误。我甚至没有获得访问令牌,所以我怀疑已超过刷新限制。如下所示,iss值设置为以“@ developer.gserviceaccount.com”结尾的客户端电子邮件地址。

我怀疑我还缺少其他东西,因为我是Python的新手,我怀疑这是一件令人尴尬的事情。也许有人可以帮忙吗?

import json
import time
import base64
import requests
from datetime import datetime

utc = datetime.utcnow()
iat = time.mktime(utc.timetuple())
exp = iat + 3600

jwt_header = {
    "alg":"RS256",
    "typ":"JWT"
}

jwt_claim_set = {
    "iss":"pleasehelpme@developer.gserviceaccount.com",
    "scope":"https://www.googleapis.com/auth/admin.directory.user",
    "aud":"https://www.googleapis.com/oauth2/v3/token",
    "iat":int(iat),
    "exp":int(exp),
    "sub":"someadminfrustrated@googleoauth.com"
}

jwt_jws = bytearray(str(jwt_header) + '.' + str(jwt_claim_set))

jwt_unencoded = str(jwt_header) + '.' + str(jwt_claim_set) + '.' +     str(jwt_jws)
jwt_encoded = base64.urlsafe_b64encode(str(jwt_unencoded))

url = 'https://www.googleapis.com/oauth2/v3/token'
headers = {
    'content-type': 'application/x-www-form-urlencoded'
}

payload = {
    'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
    'assertion': jwt_encoded
}

response = requests.post(url, headers=headers, params=payload)

print response
print response.json()

输出如下:

<Response [400]>
{u'error_description': u'Bad Request', u'error': u'invalid_grant'}

1 个答案:

答案 0 :(得分:0)

我会查看输出http和url以确保,但看起来您确实遇到了身份验证问题。

我遇到了一个类似但虽然不太复杂的问题,并且无法通过python脚本获取我的Google Developer凭据。我最终使用我的Chrome浏览器Cookie和此脚本来完成该部分:http://n8henrie.com/2014/05/decrypt-chrome-cookies-with-python/

使一切变得非常简单:

url = 'http://www.example.com'
s = requests.Session()
cookies = pyCookieCheat.chrome_cookies(url)
s.get(url, cookies = cookies)