API Google Calendar API v3 - comment obtenir un jeton de rafraîchissement (Python)

j'essaie d'écrire une application Django qui crée des événements dans un calendrier Google spécifique. Jusqu'à présent j'ai réussi. Il y a seulement un petit problème:

Je ne sais pas comment obtenir un jeton de rafraîchissement avec le client google python.

Le résultat est qu'après mon jeton d'expiration de l'application ne fonctionne pas et je dois créer un nouveau jeton. Si je comprends la documentation correcte c'est là que le actualiser jeton vient dans.

<!-Les tokens D'accès ont une durée de vie limitée et, dans certains cas, une application a besoin d'accéder à une API Google au-delà de la durée de vie d'un token d'accès unique. Lorsque c'est le cas, votre application peut obtenir ce qu'on appelle un jeton d'actualisation. Un token de rafraîchissement permet à votre application d'obtenir de nouveaux tokens d'accès.

Google Documentation (voir "Basic Steps", Section 4)

mon code

import gflags
import httplib2

from apiclient.discovery import build
from oauth2client.file import Storage
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run

FLAGS = gflags.FLAGS

FLOW = OAuth2WebServerFlow(
    client_id=GOOGLE_API_CLIENT_ID,
    client_secret=GOOGLE_API_CLIENT_SECRET,
    scope=GOOGLE_API_CALENDAR_SCOPE,
    user_agent=GOOGLE_API_USER_AGENT)

storage = Storage(GOOGLE_API_CREDENTIAL_PATH)
credentials = storage.get()
if credentials is None or credentials.invalid == True:
  credentials = run(FLOW, storage)

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

service = build(serviceName='calendar', version='v3', http=http,
   developerKey=GOOGLE_API_DEVELOPER_KEY)

event = {
    [... Dictionary with all the necessary data here ...]
}

created_event = service.events().insert(calendarId=GOOGLE_API_CALENDAR_ID, body=event).execute()

Ceci est assez bien l'exemple de Google documents. Le morceau intéressant est le Stockage. C'est un fichier où des données sont enregistrées.

le Contenu de mon fichier de stockage:

{
    "_module": "oauth2client.client", 
    "_class": "OAuth2Credentials", 
    "access_token": [redacted], 
    "token_uri": "https://accounts.google.com/o/oauth2/token", 
    "invalid": true, 
    "client_id": [redacted], 
    "client_secret": [redacted], 
    "token_expiry": "2011-12-17T16:44:15Z", 
    "refresh_token": null, 
    "user_agent": [redacted]
}

Il devrait y avoir un actualiser jeton là, mais c'est plutôt null. Donc je me suis dit que je pouvais en quelque sorte demander un actualiser jeton.

j'apprécierais toute aide sur la façon dont je peux obtenir cela pour travailler. Si vous avez besoin de plus d'informations, s'il vous plaît dites-moi.

18
demandé sur Kara 2011-12-17 22:21:20

4 réponses

Je ne sais pas comment faire avec le Client Python ou L'API Calendar (j'utilise juste une bibliothèque ruby OAuth2 pour accéder à L'API Contacts), mais j'ai trouvé que j'avais besoin de demander un accès "hors ligne" à l'utilisateur.

ceci est fait en ajoutant le paramètre " access_type "avec la valeur" offline "à l'url d'autorisation (celle que vous redirigez l'utilisateur pour cliquer sur"je veux permettre à cette application d'accéder à mes données").

Si vous faites cela, vous obtenez un refresh_token de retour dans votre réponse JSON lorsque vous demandez à google des tokens d'accès. Dans le cas contraire, vous n'obtiendrez que le jeton d'accès (valable une heure).

cette exigence a apparemment été ajoutée récemment (et pourrait ne pas être documentée merveilleusement).

vous aviez l'habitude d'obtenir un jeton de rafraîchissement sans avoir à obtenir une permission spécifique "hors ligne".

J'espère que cela vous mènera dans la bonne direction.

19
répondu bonkydog 2011-12-17 22:19:58

Donc, si vous avez déjà accepté le consentement sans paramètre access_type='offline', vous devez forcer l'utilisateur à consentir à votre application avec accès hors connexion en passant approval_prompt='force'.

self.flow = OAuth2WebServerFlow(
    client_id=self.client_id,
    client_secret=self.client_secret,
    scope=self.SCOPE,
    user_agent=user_agent,
    redirect_uri='urn:ietf:wg:oauth:2.0:oob',
    access_type='offline', # This is the default
    approval_prompt='force'
)

alors vous pouvez supprimer l'invite de force/la mettre à auto après avoir obtenu le jeton de rafraîchissement.

14
répondu yellottyellott 2013-01-12 00:24:18

Les réponses semble être obsolète depuis 2017-06-16.

  • approval_prompt est obsolète
  • prompt=force n'est pas valide

Voici un exemple:

from oauth2client.client import OAuth2WebServerFlow

flow = OAuth2WebServerFlow(
    client_id=CLIEN_ID,
    client_secret=CLIENT_SECRET,
    scope=SCOPES,
    redirect_uri='http://localhost/gdrive_auth',
    access_type='offline',
    prompt='consent',
)

print(flow.step1_get_authorize_url())
4
répondu Szabolcs Dombi 2017-06-16 09:26:23

Si vous suivez ce manuel https://developers.google.com/identity/protocols/OAuth2WebServer et vous ne pouvez pas recevoir refresh_token, essayez d'ajouter prompt= "consentement" ici:

authorization_url, state = flow.authorization_url(
    # Enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    prompt='consent',
    # Enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true')

Ici est décrit pourquoi il peut arriver

0
répondu Anatoly E 2018-08-18 16:23:36