我正在尝试将Gmail API与Python Google客户端库一起使用。
我已通过Google Developer Console创建了服务帐户凭据。
然后我尝试使用sO这样的凭据:
from oauth2client.client import SignedJwtAssertionCredentials
client_email = '<sanitised>@developer.gserviceaccount.com'
with open("foobar-<sanitised>.p12") as f:
private_key = f.read()
credentials = SignedJwtAssertionCredentials(client_email, private_key, 'https://www.googleapis.com/auth/gmail.readonly')
from httplib2 import Http
http_auth = credentials.authorize(Http())
from apiclient.discovery import build
gmail_server = build('gmail', 'v1', http=http_auth)
但是,当我尝试使用实际的Gmail API时,出现HTTP 500错误:
In [13]: threads = gmail_server.users().threads().list(userId='me').execute()
---------------------------------------------------------------------------
HttpError Traceback (most recent call last)
<ipython-input-13-a74134635cc3> in <module>()
----> 1 threads = gmail_server.users().threads().list(userId='me').execute()
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
133 else: # IGNORE
134 pass
--> 135 return wrapped(*args, **kwargs)
136 return positional_wrapper
137
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/googleapiclient/http.pyc in execute(self, http, num_retries)
721 callback(resp)
722 if resp.status >= 300:
--> 723 raise HttpError(resp, content, uri=self.uri)
724 return self.postproc(resp, content)
725
HttpError: <HttpError 500 when requesting https://www.googleapis.com/gmail/v1/users/me/threads?alt=json returned "Backend Error">
这里提到的用户显然是&#34;服务帐户&#34;不支持使用GMail API:
https://stackoverflow.com/a/24645874/139137
是否有人能够确认是否是这种情况,或者Google是否记录在任何地方?
我的假设是,由于服务帐户凭据是通过用户的Google Developer Console创建的,因此它只与该用户关联,并且应该可以正常工作吗?
修改:
我还应该提到我确实尝试将我的客户端显式添加到&#34;管理客户端API访问&#34; Google Apps管理控制台中的页面:
但是,我仍然收到HTTP 500后端错误。
此外,该页面上的帮助链接转到OAuth 1.0特定页面 - 我怀疑此页面仅适用于OAuth 1.0,尽管它没有在那里明确提及。
编辑2
此外,我应该提到我尝试使用Google API资源管理器:
https://developers.google.com/apis-explorer/#p/gmail/v1/gmail.users.messages.list?userId=me&_h=1&
使用OAuth 2.0和交互式用户流,它工作正常(即它列出了电子邮件)。
编辑3
我尝试按Jay Lee的建议添加sub
参数。
在我自己的Google Apps域中,它确实有效:
from oauth2client.client import SignedJwtAssertionCredentials
client_email = '<sanitised>@developer.gserviceaccount.com'
with open('foo-bar-<sanitised>.p12') as f:
private_key = f.read()
credentials = SignedJwtAssertionCredentials(client_email, private_key, 'https://www.googleapis.com/auth/gmail.readonly', sub='victorhooi@example.com')
from httplib2 import Http
http_auth = credentials.authorize(Http())
from apiclient.discovery import build
gmail_server = build('gmail', 'v1', http=http_auth)
threads = gmail_server.users().threads().list(userId='me').execute()
然后线程给了我:
In [12]: threads
Out[12]:
{u'nextPageToken': u'00058094761552980977',
u'resultSizeEstimate': 178,
u'threads': [{u'historyId': u'8942',
u'id': u'14abc26f1893823b',
u'snippet': u''},
{u'historyId': u'8822', u'id': u'14a4ffc2724e9384', u'snippet': u''},
{u'historyId': u'8769', u'id': u'14a36a9c6f552af3', u'snippet': u''},
{u'historyId': u'8716', u'id': u'14a31822f19bb161', u'snippet': u''},
{u'historyId': u'8671', u'id': u'14a2bee13eb87c07', u'snippet': u''},
但是,当我尝试在公司Google Apps域中使用sub参数时,当我到达以下行时:
gmail_server = build('gmail', 'v1', http=http_auth)
这给了我错误:
AccessTokenRefreshError: access_denied: Requested client not authorized.
我相当确定客户端确实存在于Google Developer's控制台中,并启用了Gmail API。我不确定为什么sub
参数会触发该错误。
然后,如果我使用公司Google Apps域上的其他帐户尝试使用相同的代码,但尚未进行委托,我会:
AccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request.
答案 0 :(得分:3)
尝试使用:
credentials = SignedJwtAssertionCredentials(client_email, private_key,
'https://www.googleapis.com/auth/gmail.readonly', sub='user@domain.com')
其中user@domain.com是您要模拟的用户。