AppEngine OAuth contrib and refresh_token
Posted by ark, ,

I thought I understood OAuth but had a bit of difficulty recently and it was all about how AppEngine and the oauth contrib package and its decorators work so I thought I’d document here.

My app was working great. My OAuth credentials worked fine in dev and worked fine on prod too. But after a while the prod credentials stopped working. Finally I ended up at this answer on stackoverflow. Specifically notice the Note/Gotcha at the end. No problem I thought I’ll just pass in approval_prompt=force and all will be well. BUT NO.

First I was using oauth2client.contrib.appengine.oauth2decorator_from_clientsecrets which didn’t allow me to pass in extra keyword arguments, once I switched to using oauth2client.contrib.appengine.OAuth2DecoratorFromClientSecrets it took my approval_prompt and admonished me that it’s been changed to prompt="consent" but even with that it still didn’t work. I added this code which helped a lot:

    credentials = decorator.credentials
    if credentials.refresh_token is None:
      logging.error('Got credentials with no refresh_token.')
      return self.error(500)

On my dev instance my credentials were fine, but in production still no refresh_token even though I was passing in prompt="consent". Turns out the AppEngine contrib package has ANOTHER layer of caching on top of memcache. So I needed to clear out CredentialsModel and memcache while we’re at it and finally it worked. Here’s the links for the dev and production datastores so you can clear yours out.

Posted Wednesday 28 December 2016 Share