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.