3

我正在使用 Python 开发 Google App Engine 应用程序。我正在使用:

  • Google Calendar API v3(访问我自己域中的日历。所以,这是安装在我域中的 Google Apps)
  • 适用于 Python 的 Google API 客户端库。
  • OAuth2 对我的域 (name@mydomain.com) 的用户进行身份验证

我以为我必须使用服务帐户,因为:

“如果您的 App Engine 应用程序需要调用 API 来访问应用程序项目拥有的数据,您可以使用服务帐户来简化 OAuth 2.0”

取自https://developers.google.com/api-client-library/python/platforms/google_app_engine#ServiceAccounts

但我不确定我是否误解了什么。我的场景(GAE 应用程序试图访问我自己域中的 Google Apps)是否是服务帐户的候选人?

我尝试了几种处理 OAuth2 的方法:

  • 如前所述,使用服务帐户
  • 使用 Google APIs 客户端库为 Python 提供的 Python 装饰器(OAuth2Decorator 和 OAuth2DecoratorFromClientSecrets)

在这两种情况下,我都会遇到相同的错误:

我完全迷路了。有什么线索吗?

提前谢谢了

4

1 回答 1

10

您不需要服务帐户,但使用一个可能有用。App Engine 上的服务帐户存在一些棘手的问题,详情请参阅库的报告问题。尝试使用Google APIs explorer看看是否有助于阐明如何使用 API。

只要您使用有权访问这些日历的帐户授权应用程序,您就可以访问它们,无论这是否在 Google App Engine 上。

在这里使用OAuth2Decorator是你最好的选择。如果你给出一个具体的例子,我很乐意提供一些代码片段来完成这项任务。

请参阅最近提出的类似问题:如何登录 appengine 中的任意用户以与 Drive SDK 一起使用?这似乎是您的用例,除了您想使用 Calendar API 而不是 Drive API。

更新:

在阅读了您的一篇文章(如果我是您,我会考虑关闭)之后,我拼凑了一个示例,可以帮助您了解如何使用装饰器。

首先,使用您的凭据,以便您的应用可以让用户对其进行授权:

from apiclient.discovery import build
import json
from oauth2client.appengine import OAuth2Decorator
import webapp2

decorator = OAuth2Decorator(
  client_id='your_client_id',
  client_secret='your_client_secret',
  scope='https://www.googleapis.com/auth/calendar')

service = build('calendar', 'v3')

然后您的主页将确保您的用户已登录,并且@decorator.oauth_required装饰器会将 OAuth 2.0 令牌保存在您的数据存储中。

class MainPage(webapp2.RequestHandler):
  @decorator.oauth_required
  def get(self):
    # This will force the user to go through OAuth
    self.response.write(...)
    # show some page to them

在您向他们显示的页面上,您可能会有一个表单,POST并且/add-eventAddEvent处理程序将能够使用令牌来发出请求。而不是使用oauth_required我们使用@decorator.oauth_aware来允许优雅的失败。如果 App Engine cookie 从他们的浏览器会话(如果他们POST来自表单)的请求中检测到用户,那么您的应用将在发出经过身份验证的日历请求之前从您的数据存储区查找 OAuth 2.0 凭据。

class AddEvent(webapp2.RequestHandler):
  @decorator.oauth_aware
  def post(self):
    if decorator.has_credentials():          
      event_name = self.request.get('event-name')
      some_event = {...}  # Create event here
      # Documented at
      # https://developers.google.com/google-apps/calendar/v3/reference/events/insert

      http = decorator.http()
      # Using 'primary' will insert the event for the current user
      request = service.events().insert(calendarId='primary', body=some_event)
      inserted = request.execute(http=http)
      self.response.write(json.dumps(inserted))
    else:
      self.response.write(json.dumps({'error': 'No credentials'})

最后,为了确保所有这些路由都能正常工作,您需要为每个处理程序和装饰器使用的 OAuth 2.0 处理程序定义路由:

app = webapp2.WSGIApplication([
    ('/', MainPage),
    ('/add-event', AddEvent),
    (decorator.callback_path, decorator.callback_handler())
    ],
    debug=True)

额外参考:

https://developers.google.com/api-client-library/python/platforms/google_app_engine

https://developers.google.com/google-apps/calendar/v3/reference/events/insert

于 2012-12-11T02:57:20.013 回答