google / gmail-oauth2-tools

Tools and sample code for authenticating to Gmail with OAuth2
Apache License 2.0
405 stars 211 forks source link

API probably doesn't send "refresh_token"s anymore. #35

Closed strizhechenko closed 3 years ago

strizhechenko commented 3 years ago

I'm trying to set up offlineimap to sync my mail from gmail. As the guide in .offlineimaprc.full mentions this repo I've cloned it and trying to run:

# ./oauth2.py --generate_oauth2_token --client_id=$my_client_id --client_secret=$my_secret
To authorize token, visit this url and follow the directions:
  https://accounts.google.com/o/oauth2/auth?client_id=$my_client_id&redirect_uri=$my_url&response_type=code&scope=https%3A%2F%2Fmail.google.com%2F
Enter verification code: $my_auth_code

but I've got a KeyError on 'refresh_token':

Traceback (most recent call last):
  File "./oauth2.py", line 347, in <module>
    main(sys.argv)
  File "./oauth2.py", line 327, in main
    print 'Refresh Token: %s' % response['refresh_token']
KeyError: 'refresh_token'

So I've added some prints to see the response:

{
  u'access_token': u'$my_access_token',
  u'scope': u'https://mail.google.com/',
  u'expires_in': 3585,
  u'token_type': u'Bearer'
}

Access_token is fine, auth works but for a single hour only. But I want a permanent solution mentioned in this wiki page. Am I doing something wrong? Problem seems to be on API side, maybe something is changed and not shown in the docs yet?

strizhechenko commented 3 years ago

Ha-ha, API isn't idempotent, it returns refresh token only on first authentication by user: https://stackoverflow.com/questions/10827920/not-receiving-google-oauth-refresh-token/10857806#10857806

"Fixed" by adding:

 def AccountsUrl(command):
@@ -184,6 +184,8 @@ def GeneratePermissionUrl(client_id, scope='https://mail.google.com/'):
   params['redirect_uri'] = REDIRECT_URI
   params['scope'] = scope
   params['response_type'] = 'code'
+  params['prompt']='consent'
+  params['access_type']='offline'
   return '%s?%s' % (AccountsUrl('o/oauth2/auth'),
                     FormatUrlParams(params))