App 引擎调用 Google API python 客户端 return 403 @oauth_required
App engine call to Google API python client return 403 with @oauth_required
这应该是一件微不足道的工作,但我无法把它弄出来。
我需要调用 Gae 的 Google 日历 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() 的 调用以错误 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?alt=json 返回 "Forbidden">
在我看来,我已经授予该应用程序访问我帐户的权限,并且 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())
调用中,但在我的其他处理程序中也是如此!位置和关键字都没有,也没有将授权的 Http 投入服务 build
改变了不当行为...
我也看不出可能会出现什么问题_helpers.py", line 133, in positional_wrapper
...
亲爱的,关于如何进一步研究的提示?
实际上,我可以插入 Acl and/or 在同一个 RequestHandler 中插入辅助日历,该请求处理程序会抛出带有 events().insert() 的 Forbidden 异常...!
我没有足够的声誉来发表评论,所以我将其作为答案:
首先,仔细检查您是否在 https://console.cloud.google.com/apis/dashboard?project=yourproject
启用了日历 api
其次。我使用了联系人 API 并发现,一旦您授予访问权限,您将无法再次获得访问权限,除非您首先撤销初始许可。当用户将我的应用程序连接到 Google 联系人,然后断开连接,然后尝试重新连接时,我遇到了这个问题——第二次重新连接会失败。要检查/撤销,请前往 https://security.google.com/settings/security/permissions
显然,问题是尝试使用 endTimeUnspecified: True
...
插入 all-day 事件
我在 google-api-python-client GitHub 跟踪器上开了一个问题:https://github.com/google/google-api-python-client/issues/334。
也许有人会调查它或post更准确的答案。
谢谢大家
这应该是一件微不足道的工作,但我无法把它弄出来。
我需要调用 Gae 的 Google 日历 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() 的 调用以错误 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?alt=json 返回 "Forbidden">
在我看来,我已经授予该应用程序访问我帐户的权限,并且 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())
调用中,但在我的其他处理程序中也是如此!位置和关键字都没有,也没有将授权的 Http 投入服务 build
改变了不当行为...
我也看不出可能会出现什么问题_helpers.py", line 133, in positional_wrapper
...
亲爱的,关于如何进一步研究的提示?
实际上,我可以插入 Acl and/or 在同一个 RequestHandler 中插入辅助日历,该请求处理程序会抛出带有 events().insert() 的 Forbidden 异常...!
我没有足够的声誉来发表评论,所以我将其作为答案:
首先,仔细检查您是否在 https://console.cloud.google.com/apis/dashboard?project=yourproject
启用了日历 api其次。我使用了联系人 API 并发现,一旦您授予访问权限,您将无法再次获得访问权限,除非您首先撤销初始许可。当用户将我的应用程序连接到 Google 联系人,然后断开连接,然后尝试重新连接时,我遇到了这个问题——第二次重新连接会失败。要检查/撤销,请前往 https://security.google.com/settings/security/permissions
显然,问题是尝试使用 endTimeUnspecified: True
...
我在 google-api-python-client GitHub 跟踪器上开了一个问题:https://github.com/google/google-api-python-client/issues/334。
也许有人会调查它或post更准确的答案。
谢谢大家