2

I'm using gspread in a python app to access some backend Google Sheets that act as a database for the application. The user is required to log into the app using an in app browser and an authlib OAuth2 session is created using the token returned in the url via this method. The initial log in and access works fine, but when the token times out after an hour I access the sheets anymore and the app breaks.

I can't work out how to refresh the token using authlib, the reason we picked the library is because it integrated with gspread and the it was supposed to autorefresh auth tokens for you. The code that I use for login is below but after an hour the gspread function open_by_key() fails because of the authentication problem.

I have tried recreating the gspread client, but that just uses the same token. I feel like there should be a way to refresh the token to extend its life for another hour but I can't find how to do that with authlib.

creds = OAuth2Session(clientId, clientSecret, scope=scope, redirect_uri=redirectUrl)
authUrl, state = creds.create_authorization_url('https://accounts.google.com/o/oauth2/v2/auth', response_type='token')

Load the authURL in the browser and get user to log in. Browser returns the authentication response as urlString

creds.fetch_access_token(authorization_response=urlString)

gc = gspread.Client(None, creds)
ss = gc.open_by_key(sheetKey)
todaysSheetName = datetime.datetime.now().strftime('%d-%m-%Y')
wks = ss.worksheet(todaysSheetName)
fooforever
  • 379
  • 1
  • 3
  • 14

1 Answers1

2
authUrl, state = creds.create_authorization_url('https://accounts.google.com/o/oauth2/v2/auth', response_type='token')

According to this code you are using, response_type=token is an implicit grant type flow. I guess there won't be a refresh_token in token with implicit flow. Here are my suggestions:

  1. try change it to authorization code flow
  2. use a database to save tokens
  3. if the token is expired, use your previously saved token's refresh_token to exchange a new token.

The refresh_token method is simple:

refresh_token(url=None, refresh_token=None, body='', auth=None, headers=None, **kwargs)

Using your code, it should be:

refresh_token = your_previous_token.refresh_token
new_token = creds.refresh_token('https://accounts.google.com/...', refresh_token=refresh_token)

The problem is that there is no documentation on this part. But according to the API, it would be used like this. If it is not working, you can report it to Authlib issue tracker.

lepture
  • 2,307
  • 16
  • 18
  • Any suggestions on how we use it in django with auto update token, tried signals and update token method as per docs but the token is not refreshed for the expired access tokens. – cric Nov 04 '21 at 01:36