GAE中的OAuth2身份验证访问Calendar API V3(域托管) [英] OAuth2 authentication in GAE accessing Calendar API V3 (domain hosted)
问题描述
我正在用Python开发Google App Engine应用程序。我使用的是:
我以为我必须使用服务帐户,因为这样:
如果您的App Engine应用程序需要调用API来访问应用程序项目拥有的数据,您可以通过使用服务帐户来简化OAuth 2.0
摘自 https://developers.google.com/api-client-library/python/platforms/google_app_engine #ServiceAccounts
但我不确定我是否误解了某些内容。我的场景(GAE应用试图访问我自己的域中的Google Apps)是服务帐户的候选人吗?
我尝试了几种方法来处理OAuth2:
>- 使用服务帐户,如前所述使用Python API客户端库提供的Python装饰器(OAuth2Decorator和OAuth2DecoratorFromClientSecrets)
在这两种情况下,我都会得到相同的错误:
这可能是客户端ID /客户端密钥或API控制台生成的服务帐户参数的问题吗?我应该重新创建它们吗?
我完全失去了。任何线索?
非常感谢您提前
t需要一个服务帐户,但使用一个可能是有用的。在中详细说明了App Engine上的服务帐户存在一些棘手问题。 nofollow noreferrer>向图书馆报告了问题。尝试稍微浏览一下 Google APIs资源管理器并查看如果这有助于澄清如何使用API。
只要您使用可访问这些日历的帐户授权应用程序,您就可以访问它们,而不管这是否在Google App Engine上。
使用 OAuth2Decorator
是您最好的选择。如果您举了一个具体示例,我很乐意提供一些代码片段来完成任务。
查看最近问到的类似问题:如何登录添加到驱动SDK中的任意用户appengine中?这似乎是您的用例,除非您想使用Calendar API而不是Drive API。
更新:
读完(如果我是你,我会考虑关闭),我已经拼凑出一个样本,可能会首先,要使用您的凭据,以便您的应用程序可以让用户授权它:
来自apiclient.discovery import build
impo rt json
from oauth2client.appengine import OAuth2Decorator
import webapp2
$ b $ 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
decorator会将OAuth 2.0标记保存到数据存储区中。
class MainPage(webapp2.RequestHandler):
@ decorator.oauth_required
def get(self):
#这将强制用户浏览OAuth
self.response.write(...)
#显示某页到他们
在显示给他们的页面上,您可能会有一个 POST
s为 / add-event
,并且这个 AddEvent
处理程序将能够使用令r的令牌eQUEST的。我们使用 @ decorator.oauth_aware
来代替使用 oauth_required
来允许优美的失败。如果用户在浏览器会话中检测到App Engine cookie的请求(如果它们是来自表单的 POST
),那么您的应用程序将查找OAuth 2.0 $凭证从您的数据存储进行认证的日历请求之前。
class AddEvent(webapp2.RequestHandler):
@decorator .oauth_aware
def post(self):
如果decorator.has_credentials():
event_name = self.request.get('event-name')
some_event = {.. 。}#在这里创建活动
#记录在
#https://developers.google.com/google-apps/calendar/v3/reference/events/insert
http = decorator.http()
#使用'primary'会为当前用户插入事件
request = service.events()。insert(calendarId ='primary',body = some_event)
插入= request.execute(http = http)
self.response.write(json.dumps(插入))
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
I'm developing a Google App Engine app with Python. And I'm using:
- Google Calendar API v3 (to access a calendar in my own domain. So, this is Google Apps installed in my domain)
- Google APIs client library for Python.
- OAuth2 to authenticate users of my domain (name@mydomain.com)
I thought I had to use Service Accounts, because of this:
"If your App Engine application needs to call an API to access data owned by the application's project, you can simplify OAuth 2.0 by using Service Accounts"
Taken from https://developers.google.com/api-client-library/python/platforms/google_app_engine#ServiceAccounts
But I'm not sure if I misunderstood something. Is my scenario (GAE app trying to access Google Apps in my own domain) a candidate for Service Accounts?
I've tried several ways to handle OAuth2:
- With Service Accounts, as said
- With Python decorators provided by Google APIs client library for Python (OAuth2Decorator and OAuth2DecoratorFromClientSecrets)
In both cases, I get the same errors:
- Executing in my local machine: HttpError 401 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/events?alt=json returned "Invalid Credentials" (I created the event as JSON object, following this: https://developers.google.com/google-apps/calendar/v3/reference/events/insert#examples). An error stack trace: https://dl.dropbox.com/u/61566717/output/local_error
- Deploying to GAE: Error 310 (net::ERR_TOO_MANY_REDIRECTS). The string "_ah/login_required?continue=" is appended at the end of the url several times. May it be a problem with the Client ID/client secret or the Service Account parameters generated with API console? Should I re-create them?
I'm totally lost. Any clues?
Many thanks in advance
You don't need a service account, though using one may be useful. There are some tricky issues with service accounts on App Engine detailed in a reported issue with the library. Try playing around with the Google APIs explorer a bit and see if that helps clarify how to use the API.
As long as you authorize the application with an account that has access to those calendars, you will be able to access them, irrespective of whether or not this is on Google App Engine.
Using the OAuth2Decorator
is your best bet here. If you give a specific example I'd be happy to provide some code snippets for accomplishing the task.
See a similar question asked recently: How can I log in to an arbitrary user in appengine for use with the Drive SDK? This seems to be your use case, except you want to use the Calendar API instead of the Drive API.
UPDATE:
After reading your other post (which I would consider closing, if I were you), I have pieced together a sample that may help you understand how to use the decorator.
First, to use your credentials so your app can let user's authorize it:
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')
Then your main page will make sure your users are signed in and the @decorator.oauth_required
decorator will save the OAuth 2.0 tokens in your datastore.
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
On the page you display to them, you would likely have a form that POST
s to /add-event
and this AddEvent
handler will be able to use the token to make the request. Instead of using oauth_required
we use @decorator.oauth_aware
to allow graceful failure. If a user is detected in the request by the App Engine cookies from their browser session (which they will be if they POST
from a form), then your app will lookup the OAuth 2.0 credentials from your datastore before making the authenticated calendar request.
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'})
Finally, to make sure all those routes work, you'll need to define routes for each handler and the OAuth 2.0 handler used by the decorator:
app = webapp2.WSGIApplication([
('/', MainPage),
('/add-event', AddEvent),
(decorator.callback_path, decorator.callback_handler())
],
debug=True)
Extra Reference:
https://developers.google.com/api-client-library/python/platforms/google_app_engine
https://developers.google.com/google-apps/calendar/v3/reference/events/insert
这篇关于GAE中的OAuth2身份验证访问Calendar API V3(域托管)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!