¿Cómo hacer las operaciones OAuth2 ‘access_type = offline’ / solo servidor en GAE / Python?

Esta publicación es un seguimiento de ¿Cómo hacer operaciones que requieren OAuth en un trabajo cron de GAE? , donde me di cuenta de que estoy usando @oauth_required decorador OAuth2DecoratorFromClientSecrets de OAuth2DecoratorFromClientSecrets .

Como se describe en la presentación explicada de OAuth 2.0 , Oauth 2.0 resuelve el problema de:

  • Construyendo un servicio
  • … accedido por un usuario
  • y accediendo a los datos del usuario desde un tercero .

Eso es lo que @oauth_required abstrae, y lo hace bien (actualmente mi aplicación “funciona”: si activo la página de actualización, me piden que autorice el acceso a mis datos de youtube a mi aplicación, y el rest sigue). ¡Pero eso no es lo que quiero! Mi aplicación hace algo más simple, que es crear una lista de reproducción de youtube todos los días con mis credenciales y sin ninguna entrada por parte del usuario . Así que para comparar con la negociación de 3 niveles anterior, quiero:

  • Un servicio
  • … accedido por los usuarios
  • pero solo accediendo a los datos de la lista de reproducción de YouTube “propiedad del servidor”. No quiero ningún acceso a los datos de YouTube del usuario, solo quiero modificar una lista de reproducción que poseo (es decir, yo / un usuario persistido por el servidor).

Pero todavía necesito ayuda para hacer eso; Aquí está mi estado actual:

  1. Después de algunas búsquedas, aprendí que lo que quiero hacer se llama Acceso sin conexión (el énfasis es mío, que es casi exactamente mi caso de uso):
    “En algunos casos, es posible que su aplicación necesite acceder a la API de Google cuando el usuario no está presente. Algunos ejemplos incluyen servicios de respaldo y aplicaciones que hacen que las publicaciones de bloggers sean exactamente a las 8 am del lunes por la mañana . Este estilo de acceso se llama offline y web. las aplicaciones de servidor pueden solicitar el acceso sin conexión a un usuario. El estilo de acceso normal y predeterminado se llama en línea “.
    → Por lo tanto, debería seguir haciendo lo que estoy haciendo en este momento, seguir solicitando acceso a mi cuenta de YouTube, pero hacerlo utilizando el type_access=offline para obtener un token, y persistir / usarlo para solicitudes posteriores.

  2. Las secciones Acceso sin conexión y Uso de un token de actualización tienen mucho sentido, pero se mantienen en un nivel HTTP general. Siendo todavía un novato, no veo cómo integrar esos principios en mi código de Python, y no encontré ningún código de Python de ejemplo alrededor …
    → ¿Podría alguien ayudarme con un ejemplo de Python que ilustre cómo y dónde usar esta bandera?

  3. … y, en particular, después de estudiar oauth2client.appengine.OAuth2Decorator.oauth_required , todavía no estoy seguro de si puedo oauth2client.appengine.OAuth2Decorator.oauth_required a mi caso, o si debo hacer lo mío.
    → ¿Qué piensas?

Gracias por tu tiempo; si es necesario, también estoy en irc: //irc.freenode.net/#appengine as ronj .

El acceso sin conexión es el predeterminado cuando se recuperan tokens; Es posible que haya notado esto en el cuadro de diálogo OAuth que aparece:

Realizo estas operaciones cuando no estoy usando la aplicación.

Cuando su usuario acepte el cuadro de diálogo OAuth en un método decorado con decorator.oauth_required las credenciales de ese usuario se almacenarán en el almacén de datos, incluido el token de actualización.

Una vez que tenga uno de estos objetos de credenciales, puede usarlo para autorizar un objeto HTTP para llamar a APIS:

 import httplib2 http = credentials.authorize(httplib2.Http()) 

y una vez autorizado, hará todo el trabajo por ti. Por lo tanto, si el access_token ha caducado, la primera respuesta de la API será 401 y, por lo tanto, el objeto de credentials utilizará el refresh_token para obtener un nuevo access_token y volver a realizar la solicitud.

Si conoce el ID de usuario, puede recuperar las credentials del almacén de datos como se describe en ¿Cómo realizar operaciones que requieren OAuth en una cola de tareas de GAE? :

 from oauth2client.appengine import CredentialsModel from oauth2client.appengine import StorageByKeyName credentials = StorageByKeyName( CredentialsModel, user_id, 'credentials').get() 

Nota / Gotcha:

Si un usuario ya ha autorizado su ID de cliente, las siguientes veces que realice OAuth para estos usuarios no verán el cuadro de diálogo OAuth y no se le dará un token de actualización. Solo se puede dar un token de actualización si atraviesan el cuadro de diálogo OAuth, pero como el usuario ya había autorizado su ID de cliente, la especificación asume que ya tendría un token de actualización.

Esto ocurre a menudo cuando los desarrolladores están probando OAuth, ya que pasarán por el flujo varias veces con una cuenta de prueba y, después de aceptar el 2º, 3º, 4º tiempo, nunca verán el token de actualización. Una forma sencilla de evitar esto es usar el OAuth2Decorator approval_prompt=force como argumento para el constructor OAuth2Decorator . Esto obligará a que aparezca el cuadro de diálogo OAuth cada vez que realice OAuth para un usuario.

Sin embargo, esto no hará que el diálogo se muestre cada vez que se sirva una solicitud para un usuario determinado; Esto sería una experiencia de usuario TERRIBLE . En su lugar, la cookie SACSID de la solicitud puede ser utilizada (por la biblioteca cliente y algunas bibliotecas de App Engine) para determinar quién es el usuario actual. Una vez que la biblioteca conozca a ese usuario actual, puede obtener su token / credentials almacenada existente para ese usuario desde el almacén de datos y no será necesario un diálogo de discordancia.