Search code examples
pythondjangooauth-2.0google-oauthpython-social-auth

Python Social Auth, Google, and refresh token


In a personal project, I am trying to use Django as my front end and then allow data entered by users in a particular form to be copied to google sheets.

Google's own docs recommend using https://github.com/google/oauth2client which is now deprecated, and the docs have not been updated. With this, I have started attempting to use Python Social Auth and Gspread. For Gspread to be able to function correctly, I need to be able to pass it not only an access token but also a refresh token. Python Social Auth however is not persisting the refresh token along with the rest of the "extra data". Looking at the data preserved and the URLs routed to, it seems to me more like somewhere it is routing through Google+.

I have the following configurations in my Django settings files:

AUTHENTICATION_BACKENDS = (
    'social_core.backends.google.GoogleOAuth2',
    'django.contrib.auth.backends.ModelBackend',
)

SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
    'social_core.pipeline.social_auth.associate_by_email',
)    

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '...'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '...'
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = ['https://www.googleapis.com/auth/spreadsheets']
  • Is there a better way to access a google sheet?
  • Am I correct that PSA or google is redirecting me into a Google+ auth flow instead of the Google Oauth2?
  • If not, what must change so that Python Social Auth keeps the refresh token?

Solution

  • It's true that python-social-auth will use some bits of the Google+ platform, at least the API to retrieve details about the user to fill in the account.

    From your settings, I see you have associate_by_email at the bottom, at that point, at that point it has no use since the user is already be created, if you really plan to use it, it must be before the create_user one, you can check the DEFAULT_PIPELINE as a reference.

    In order to get a refresh_token from google, you need to tell it that you want one, to do that you need to set the offline access type:

    SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {
      'access_type': 'offline'
    }
    

    With that setting Google will give you a refresh_token and it will automatically stored in extra_data.