【问题标题】:OAuth2 authentication in GAE accessing Calendar API V3 (domain hosted)GAE 中的 OAuth2 身份验证访问 Calendar API V3(域托管)
【发布时间】:2015-04-29 08:17:06
【问题描述】:

我正在使用 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 API 客户端库为 Python 提供的 Python 装饰器(OAuth2Decorator 和 OAuth2DecoratorFromClientSecrets)

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

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

在此先感谢

【问题讨论】:

    标签: python google-app-engine oauth-2.0 google-calendar-api google-api-python-client


    【解决方案1】:

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

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

    使用OAuth2Decorator 是您最好的选择。如果你给出一个具体的例子,我很乐意提供一些代码 sn-ps 来完成任务。

    查看最近提出的类似问题:How can I log in to an arbitrary user in appengine for use with the Drive SDK? 这似乎是您的用例,但您想使用日历 API 而不是 Drive API。

    更新:

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

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

    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
    

    在您向他们显示的页面上,您可能会有一个POSTs 到/add-event 的表单,而这个AddEvent 处理程序将能够使用令牌来发出请求。我们不使用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

    【讨论】:

    • 很好的回应!非常感谢。我将我的代码减少到它工作的最低限度。现在,我有更多问题,但我会提出其他问题。再次感谢!
    • 您的appengine.py 版本中真的存在decorator.callback_pathdecorator_callback_handler() 吗?我有一个类似的问题here,我正在为这些回调参数而苦苦挣扎,请问您可以看看吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 1970-01-01
    • 2023-04-01
    • 2017-03-01
    • 1970-01-01
    • 2017-05-05
    相关资源
    最近更新 更多