当前位置: 首页 > 知识库问答 >
问题:

Gmail API支持使用OAuth服务帐户吗?

刘弘济
2023-03-14

我正在尝试将Gmail API与Python Google客户端库结合使用。

我已经通过Google开发者控制台创建了服务帐户凭据。

然后我尝试使用这些凭证,如下所示:

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">

一位用户在这里提到,显然“服务账户”不支持使用GMail应用编程接口:

https://stackoverflow.com/a/24645874/139137

是否有人能够确认这是真的,或者谷歌是否在任何地方记录了此事?

我的假设是,由于服务帐户凭据是通过用户的Google Developer控制台创建的,所以它只会与该用户关联,应该可以正常工作?

编辑:

我还应该提到,我确实尝试将我的客户端显式添加到谷歌应用程序管理控制台中的“管理客户端应用编程接口访问”页面:

然而,我仍然得到HTTP 500后端错误。

此外,该页面上的帮助链接指向OAuth 1.0特定页面——我怀疑该页面仅适用于OAuth 1.0,尽管那里没有明确提到。

编辑2

此外,我应该提到,我曾尝试在以下位置使用Google API Explorer:

https://developers.google.com/apis-explorer/#p/gmail/v1/gmail.users.messages.list?userId=me

使用OAuth 2.0和交互式用户流,它工作正常(即它列出电子邮件)。

编辑3

我试着按照Jay Lee的建议添加sub参数。

在我自己的谷歌应用程序域,它确实有效:

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''},

然而,当我尝试在我的公司谷歌应用程序域中使用sub参数时,当我到达以下行时:

gmail_server = build('gmail', 'v1', http=http_auth)

这给了我错误:

AccessTokenRefreshError: access_denied: Requested client not authorized.

我相当确定客户端确实存在于Google Developer的控制台中,并且Gmail API已启用。我只是不确定为什么sub参数会触发该错误。

然后,如果我在公司的谷歌应用程序域中使用不同的帐户尝试相同的代码,但没有被授权,我会得到:

AccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request.

共有1个答案

林正平
2023-03-14

尝试使用:

credentials = SignedJwtAssertionCredentials(client_email, private_key,
  'https://www.googleapis.com/auth/gmail.readonly', sub='user@domain.com')

哪里user@domain.com是您希望模拟的用户。

 类似资料:
  • 我对Google Drive API、服务帐户和身份验证有一些问题。我读了很多书,但我不知道如何解决这个问题。 上下文:我的驱动器帐户上有一些文件(约35GB)和一个简单的web应用程序,用户可以登录,从我的驱动器中查看一些选定的文件夹/文件,并在需要时下载它们。唯一可以直接访问我的驱动器帐户的人是(或应该是)我的服务器,用户通过web app/server完成他们的工作。 经过一番搜索,我发现服

  • 谷歌推荐的方法是什么?如何最好地获得谷歌驱动器帐户的访问权,同时只需要所有者一次性验证,但允许他们随时撤销访问权?

  • 我正在尝试通过服务帐户(客户端电子邮件和p12证书)连接到google doubeclick api,使用python客户端库,如以下示例所示: http://code.google.com/p/google-api-python-client/source/browse/samples/service_account/tasks.py 它给我一个空access_token: 这有什么意义?我有没

  • 我想用gmail API阅读我的gmail收件箱。我需要使用服务帐户,因为我的应用程序没有用户交互。我在请求时收到以下错误: 这是我的代码: 我做错了什么?有人能帮我吗? 当做

  • 我们构建了一个应用程序,该应用程序试图使用服务帐户访问谷歌日历应用编程接口。我们自己管理应用程序,但是我们尝试访问的日历在一个单独的谷歌办公套件帐户上。我们已经让谷歌办公套件管理员按照此处的步骤,允许根据客户端ID和“https://www.googleapis.com/auth/calendar.readonly.”的身份验证范围访问我们的应用程序 现在,当使用服务帐户尝试访问用户日历数据时,我

  • 我正面临着以下问题:我已经创建了一个谷歌服务帐户,现在我正在尝试使用c#对谷歌API和YouTube数据API进行授权API调用。以下是我的示例代码: 代码生成成功,但当我启动程序时,我收到以下错误消息: 系统.IO.File未发现异常:“无法加载文件或程序集”弹跳卡思加密,版本=1.7.4137.9688,区域性=非特定,公钥令牌=a4292a325f69b123“或其依赖项之一。系统找不到指定