Autenticación OAuth2 en GAE accediendo a Calendar API V3 (dominio alojado)

Estoy desarrollando una aplicación Google App Engine con Python. Y estoy usando:

  • Google Calendar API v3 (para acceder a un calendario en mi propio dominio. Entonces, esto es Google Apps instalado en mi dominio)
  • Biblioteca de clientes API de Google para Python.
  • OAuth2 para autenticar a los usuarios de mi dominio (name@mydomain.com)

Pensé que tenía que usar las cuentas de servicio, debido a esto:

“Si su aplicación App Engine necesita llamar a una API para acceder a los datos que pertenecen al proyecto de la aplicación, puede simplificar OAuth 2.0 utilizando las Cuentas de servicio”

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

Pero no estoy seguro si entendí mal algo. ¿Mi escenario (la aplicación GAE intenta acceder a Google Apps en mi propio dominio) es un candidato para cuentas de servicio?

He intentado varias formas de manejar OAuth2:

  • Con cuentas de servicio, como se ha dicho.
  • Con los decoradores de Python proporcionados por la biblioteca cliente de Google API para Python (OAuth2Decorator y OAuth2DecoratorFromClientSecrets)

En ambos casos, obtengo los mismos errores:

  • Ejecutando en mi máquina local: HttpError 401 al solicitar https://www.googleapis.com/calendar/v3/calendars/primary/events?alt=json devolvió “Credenciales no válidas” (creé el evento como objeto JSON, a continuación: https://developers.google.com/google-apps/calendar/v3/reference/events/insert#examples ). Un seguimiento de la stack de errores: https://dl.dropbox.com/u/61566717/output/local_error
  • Implementación en GAE: Error 310 (net :: ERR_TOO_MANY_REDIRECTS). La cadena “_ah / login_required? Continue =” se adjunta al final de la URL varias veces. ¿Puede ser un problema con el ID de cliente / secreto de cliente o los parámetros de la cuenta de servicio generados con la consola API? ¿Debo recrearlos?

Estoy totalmente perdido. ¿Alguna pista?

Muchas gracias de antemano

No necesita una cuenta de servicio, aunque usar una puede ser útil. Hay algunos problemas complicados con las cuentas de servicio en App Engine que se detallan en un problema reportado con la biblioteca. Intente jugar un poco con el explorador de API de Google y vea si eso ayuda a aclarar cómo usar la API.

Siempre que autorice la aplicación con una cuenta que tenga acceso a esos calendarios, podrá acceder a ellos, independientemente de si se trata de Google App Engine o no.

Usar el OAuth2Decorator es tu mejor apuesta aquí. Si da un ejemplo específico, me encantaría proporcionarle algunos fragmentos de código para realizar la tarea.

Vea una pregunta similar hecha recientemente: ¿Cómo puedo iniciar sesión en un usuario arbitrario en appengine para usar con el SDK de Drive? Este parece ser su caso de uso, excepto que desea utilizar la API de calendario en lugar de la API de Drive.

ACTUALIZAR:

Después de leer tu otra publicación (que consideraría un cierre, si fuera tú), he juntado una muestra que puede ayudarte a entender cómo usar el decorador.

Primero, use sus credenciales para que su aplicación permita que el usuario lo autorice:

 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') 

Luego, su página principal se asegurará de que sus usuarios hayan @decorator.oauth_required sesión y el @decorator.oauth_required guardará los tokens OAuth 2.0 en su almacén de datos.

 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 

En la página que les muestre, es probable que tenga un formulario que AddEvent POST a /add-event y este controlador AddEvent podrá usar el token para realizar la solicitud. En lugar de usar oauth_required , usamos @decorator.oauth_aware para permitir un fallo gracioso. Si las cookies de App Engine detectan un usuario en la solicitud de su sesión del navegador (que será si POST de un formulario), entonces su aplicación buscará las credenciales de OAuth 2.0 de su almacén de datos antes de realizar la solicitud de calendario autenticada.

 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'}) 

Finalmente, para asegurarse de que todas esas rutas funcionen, deberá definir rutas para cada controlador y el controlador OAuth 2.0 utilizado por el decorador:

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

Referencia Extra:

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

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

Realmente luché en un esfuerzo reciente para integrar Google Calendar. Escribí mi propia documentación. Tal vez ayude:

http://www.tqis.com/eloquency/googlecalendar.htm