Google Calendar API v3 - How to obtain a refresh token (Python)

痞子三分冷 提交于 2019-11-30 03:17:41

I don't know how to do this with the Python Client or the Calendar API (I'm just using a ruby OAuth2 library for access to the Contacts API), but I found I needed to request "offline" access from the user.

This is done by adding the an "access_type" parameter with the value "offline" to the authorization url (the one you redirect the user to to click "I want to allow this application to get at my data").

If you do this, you get a refresh_token back in your JSON response when you ask google for access tokens. Otherwise you only get the access token (which is valid for an hour).

This requirement was apparently added recently (and may not be wonderfully documented).

You used to get a refresh token without having to get specific "offline" permission.

Hope this points you in the right direction.

So if you've already accepted consent without setting access_type='offline', you need to force the user to consent to your app with offline access by also passing 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'
)

Then you can remove the force prompt/set it to auto after you get the refresh token.

The answers seems to be deprecated as of 2017-06-16.

  • approval_prompt is deprecated
  • prompt=force is not valid

Here is a working example:

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

If you follow this manual https://developers.google.com/identity/protocols/OAuth2WebServer and you can not receive refresh_token, try to add prompt='consent' here:

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

Here is described why it can happen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!