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.