应用引擎调用Google API python客户端返回403 @oauth_required

时间:2017-01-04 15:52:44

标签: ajax google-app-engine google-api google-api-client google-api-python-client

这应该是一项微不足道的工作,但我无法解决。

我需要从Gae调用Google Calendar API;因此,我按照Google文档和示例设置了所有内容:

我是/auth.py

CLIENT_SECRETS = os.path.join(os.path.dirname(__file__), 'client_secrets.json')
SCOPES = [
    'https://www.googleapis.com/auth/calendar',
]
decorator = appengine.OAuth2DecoratorFromClientSecrets(
    filename=CLIENT_SECRETS,
    scope=SCOPES,
    cache=memcache,
    prompt='consent',
)

main.py函数调用:

class Landing(webapp2.RequestHandler):
    @auth.decorator.oauth_aware
    def get(self):
        if auth.decorator.has_credentials():
            self.redirect('/in')
        else:
            self.response.out.write('''
            etc. {}'''.format(auth.decorator.authorize_url()))

class Main(webapp2.RequestHandler):
    @auth.decorator.oauth_required
    def get(self):
        links = { ... }
        render(self, 'base.html', template_values=links)

class Calendar(webapp2.RequestHandler):
    @auth.decorator.oauth_required
    def get(self):
        service = build('calendar', 'v3', http=auth.decorator.http())
        api_request = service.events().list(calendarId='primary')
        api_response = api_request.execute()
        self.response.headers['Content-Type'] = 'application/json; charset=utf-8'
        self.response.out.write(json.dumps(api_response, indent=4))

class PutEvent(webapp2.RequestHandler):
    @auth.decorator.oauth_required
    def post(self):
        # ...
        # http = httplib2.Http(memcache)
        service = build('calendar', 'v3') #, http=http)

        api_response = []
        for i in json.loads(self.request.get('events')):
            # ...
            event = { ... } # Google Calendar event
            api_request = service.events().insert(calendarId='primary', body=scadenza)
            api_response.append(api_request.execute(http=auth.decorator.http()))

        self.response.headers['Content-Type'] = 'application/json; charset=utf-8'
        self.response.out.write(json.dumps(api_response, indent=4))

正如您所看到的,Ajax jQuery调用(post ...

请求这是一个相当简单的$.post('{{ putEvent_url }}', jsonData, function( data ){ console.log(data); })

我在开发服务器中使用test@example用户,该应用有权访问我个人帐户的Google日历。

对我来说奇怪的是,对Calendar()的任何调用都按预期工作,但调用PutEvent()以ERROR 500 结束。

在控制台中查看回溯的结尾:

  File "/home/pierpaolo/Devnos/whiterabbit/include/oauth2client/contrib/appengine.py", line 644, in check_oauth
    resp = method(request_handler, *args, **kwargs)
  File "/home/pierpaolo/Devnos/whiterabbit/main.py", line 211, in post
    api_response.append(api_request.execute(http=auth.decorator.http()))
  File "/home/pierpaolo/Devnos/whiterabbit/include/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/home/pierpaolo/Devnos/whiterabbit/include/googleapiclient/http.py", line 838, in execute
    raise HttpError(resp, content, uri=self.uri)
HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/events?alt=json returned "Forbidden">
INFO     2017-01-04 15:13:32,385 module.py:788] default: "POST /api/put/scadenze HTTP/1.1" 500 -

我无法理解

HttpError:https://www.googleapis.com/calendar/v3/calendars/primary/events?val = json返回&#34;禁止&#34;&gt;

在我看来,我已经授予了应用程序对我帐户的访问权限,并且已正确设置Google App Engine装饰器,以便根据https://developers.google.com/api-client-library/python/guide/google_app_engine生成OAuth2.0 ...

修改 我想知道我的麻烦是否与我称之为Google Calendar API的方式有关:

     HTML/JS            GAE/Py
+------------------+
|                  |
| <form>           |
|   ...data        |
| <\JS/Ajax        |
|   $.post(...data |  -->  GAE/main.py
|                  |         @auth.decorator.oauth_required
|                  |         def post(self, data):
+------------------+           event = elaborate(data)
                               service = build('calendar', 'v3')
                               api_request = service.events()
                                             .insert(calendarId='primary',
                                                     body=event)
                               api_response = api_request
                                              .execute(auth.decorator
                                                           .http())
                               self.response(api_response)

编辑3: 我看了一下oauth2client.contrib.appengine,我在这里和那里添加了一些logger.debug:我认为问题可能在execute(http=decorator.http())调用,但在我的其他处理程序中也是如此!无论是位置还是关键字,还是将服务build中的authrized Http都改变了错误行为......

我也无法看到_helpers.py", line 133, in positional_wrapper ...

会带来什么问题

亲爱的,有些人暗示如何进一步研究?

实际上,我可以插入Acl和/或在同一个RequestHandler中插入一个辅助日历,它会抛出带有events()的Forbidden异常.insert()...!

2 个答案:

答案 0 :(得分:0)

我没有足够的声誉来评论,所以我只是留下它作为答案:

首先,仔细检查您是否已在https://console.cloud.google.com/apis/dashboard?project=yourproject

启用了calandar api

其次。我已经使用过联系人API,并发现一旦您获得访问权限,一旦您无法再次授予访问权限,除非您首先撤销初始限额。当用户将我的应用程序连接到Google通讯录,然后断开连接,然后尝试重新连接时,我遇到了这种情况 - 第二次重新连接会失败。要查看/撤消,请转到https://security.google.com/settings/security/permissions

答案 1 :(得分:0)

显然,问题是尝试使用endTimeUnspecified: True插入一整天的活动......

我在google-api-python-client GitHub跟踪器上打开了一个问题:https://github.com/google/google-api-python-client/issues/334

也许有人会调查或发布更准确的答案。

谢谢大家。