google - Autenticando a Calendar con Python gdata y oAuth 2
jwt google oauth (1)
Estoy migrando una aplicación de Python de oAuth 1 a oAuth 2 que lee el feed del calendario de Google de un usuario.
Con oAuth 1: Mi aplicación abriría un navegador si el usuario pudiese autenticarse con su cuenta de GMail y autorizara el acceso, y mi aplicación obtendría un user_token, user_secret para ese usuario, y luego se autenticaría en el feed del calendario:
client = gdata.calendar.client.CalendarClient(source=''test'') client.auth_token = gdata.gauth.OAuthHmacToken(app_key, app_secret,user_token,user_secret,gdata.gauth.ACCESS_TOKEN)
Este token, el par secreto sería de larga vida.
- Con oAuth 2: registré mi aplicación en la consola API de Google y obtuve oAuth 2 client_id y client_secret, y modifiqué la aplicación para solicitar el acceso de usuario_token, refresh_token de https://accounts.google.com/o/oauth2/token para la lib de GData, apliqué el parche gauth.py especificado aquí: http://codereview.appspot.com/4440067/
Este access_token es efímero.
Jugué un poco con el código publicado aquí http://codereview.appspot.com/4440067/ y funciona bien.
Mis preguntas:
-Estoy obteniendo access_token, refresh_token a través de una llamada curl desde mi aplicación, y puedo recuperar ambos exitosamente. Sin embargo, cuando lo aplique a este código:
token =
gdata.gauth.OAuth2Token(client_id=client_id,client_secret=client_secret'',
scope=''https://www.google.com/calendar/
feeds'',user_agent=''calendar-cmdline-sample/1.0'')
uri = token.generate_authorize_url()
token.get_access_token(access_token)
Me da:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.6/site-packages/gdata/gauth.py", line 1267,
in get_access_token
raise OAuth2AccessTokenError(error_msg)
gdata.gauth.OAuth2AccessTokenError
-Suponiendo que puedo hacer lo anterior con éxito, puedo guardar los tokens de acceso / actualización en un DB. Usando python gdata lib, ¿cómo puedo usar refresh_token para solicitar otra access_token (por lo tanto, no tener que preguntarle al usuario cada vez que use la aplicación para autorizar el acceso)?
¡Muchas gracias de antemano!
METRO
Marchie,
No veo el resto del seguimiento de tu pila, pero puedo darte tres problemas particulares con las soluciones correspondientes que resolverán tu problema general.
Problema I : El valor redirect_uri
no está establecido en el objeto.
Observe cómo se especifica el cuerpo de la solicitud en get_access_token
:
body = urllib.urlencode({
''grant_type'': ''authorization_code'',
''client_id'': self.client_id,
''client_secret'': self.client_secret,
''code'': code,
''redirect_uri'': self.redirect_uri,
''scope'': self.scope
})
Esto depende de que la propiedad redirect_uri
se establezca en el objeto con el valor que se estableció originalmente en generate_authorize_url
. Entonces, después de reconstruir el token llamando
token = gdata.gauth.OAuth2Token(...)
simplemente tendrá que configurar el URI de redirección:
token.redirect_uri = ''http://path/that/you/set''
Problema II : el valor predeterminado de redirect_uri
es incorrecto (más específicamente, obsoleto).
Como llamó a generate_authorize_url
sin argumentos, se usó el valor predeterminado para redirect_uri
, que actualmente es oob
. A medida que el estado de los documentos OAuth 2.0 , el oob
no se encuentra entre los valores admitidos (ha quedado obsoleto).
Si de hecho está utilizando una aplicación instalada, tendrá que configurarla para
token.redirect_uri = ''urn:ietf:wg:oauth:2.0:oob''
Además, cuando llame a generate_authorize_url
para obtener el token inicial, tendrá que usar esto como un parámetro de palabra clave
url = token.generate_authorize_url(redirect_uri=''urn:ietf:wg:oauth:2.0:oob'')
Problema III : Usted está llamando a get_access_token
con el valor incorrecto (también uno que no ha sido instanciado en su fragmento de código).
Debe llamar esto con un valor de cadena del código que recibe después de autorizar o con un diccionario que tiene ''code''
.
Esto se puede hacer a través de lo siguiente:
import atom.http_core
# Page the user is redirected to after authorizing
redirected_page = ''http://path/that/you/set?code=RANDOM-CODE''
uri = atom.http_core.ParseUri(redirected_page)
# uri.query is a dictionary with the query string as key, value pairs
token.get_access_token(uri.query)
Escritura posterior : el autor del parche también publicó una publicación de blog sobre el uso del parche. (Tenga en cuenta que hay un error tipográfico en la publicación cuando se utiliza la palabra clave redirect_url
lugar de redirect_uri
en la función generate_authorize_url
).