kulpa / google-api-python-client

Automatically exported from code.google.com/p/google-api-python-client
Other
0 stars 0 forks source link

Refresh token not returned when approval_prompt=auto #186

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Send a request to obtain token
2. Skip the approval_prompt parameter (or set it to "auto")
3. No refresh token is returned

What is the expected output? What do you see instead?
I expect to get both access_token and refresh_token, I only get access_token.

What version of the product are you using? On what operating system?
https://developers.google.com/accounts/docs/OAuth2WebServer

Please provide any additional information below.
If approval_prompt=force is set, I get refresh_token as well.

Original issue reported on code.google.com by nakti...@gmail.com on 30 Aug 2012 at 9:19

GoogleCodeExporter commented 9 years ago
If you need a refresh token then you need to set access_type=offline. That's 
the default for OAuth2WebServerFlow:

  http://code.google.com/p/google-api-python-client/source/browse/oauth2client/client.py#1045

  https://developers.google.com/accounts/docs/OAuth2WebServer#formingtheurl

Original comment by jcgregorio@google.com on 30 Aug 2012 at 1:15

GoogleCodeExporter commented 9 years ago
The access_type is always set to "offline" (as specified in the docs) in these 
requests. Would it help if I email you the exact query parameters I'm sending?

Original comment by nakti...@gmail.com on 30 Aug 2012 at 1:23

GoogleCodeExporter commented 9 years ago
This query:
https://accounts.google.com/o/oauth2/auth?access_type=offline&redirect_uri=http%
3A%2F%2Fexample.com%2Fcallback&response_type=code&client_id=<client_id>.apps.goo
gleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ftasks

Gives this result (no refresh token):
{u'access_token': u'...', u'token_type': u'Bearer', u'expires_in': 3600}

On the other hand, with this query:
https://accounts.google.com/o/oauth2/auth?access_type=offline&redirect_uri=http%
3A%2F%2Fexample.com%2Fcallback&response_type=code&client_id=<client_id>.apps.goo
gleusercontent.com&approval_prompt=force&scope=https%3A%2F%2Fwww.googleapis.com%
2Fauth%2Ftasks

The result contains the refresh token:
{u'access_token': u'...', u'token_type': u'Bearer', u'expires_in': 3600, 
u'refresh_token': u'...'}

1. Does this mean I have to always force the dialog to get the refresh token?

2. Is this a documented behaviour?

Original comment by nakti...@gmail.com on 3 Sep 2012 at 9:32

GoogleCodeExporter commented 9 years ago
No, you shouldn't need to force the dialog to get the refresh token. Can you 
try revoking your token and then going through the flow again?

Original comment by jcgregorio@google.com on 3 Sep 2012 at 5:19

GoogleCodeExporter commented 9 years ago
OK. So here's the issue. When I revoke the token and authorize again - I get 
the refresh token, but only once.

When I try authorizing again I get a new "access_token", but no 
"refresh_token". This new access_token is essentially useless, because it will 
expire and can not be refreshed.

Is it possible to always return a "refresh_token" when a new "access_token" is 
issued?

Original comment by nakti...@gmail.com on 3 Sep 2012 at 6:04

GoogleCodeExporter commented 9 years ago
"""
OK. So here's the issue. When I revoke the token and authorize again - I get 
the refresh token, but only once.

When I try authorizing again I get a new "access_token", but no "refresh_token".
"""

Once you have a refresh token you don't need to authorize again, you should use 
the refresh token to get a new access token.

Are you using the python client library, because it automatically adds in the 
access_type=offline to the URI so you shouldn't have this problem.

Original comment by jcgregorio@google.com on 4 Sep 2012 at 1:22

GoogleCodeExporter commented 9 years ago
I don't have a problem with "access_type=offline" - I always pass it. I have a 
problem with a new access token being issued without a respective refresh token.

"""
Once you have a refresh token you don't need to authorize again, you should use 
the refresh token to get a new access token.
"""

Does this mean that when a new access_token is issued without a refresh token 
(as I've described before), I can still use the old refresh token to refresh 
this new access_token?

Original comment by nakti...@gmail.com on 4 Sep 2012 at 1:27

GoogleCodeExporter commented 9 years ago
Are you using the python client library code? All of this should be taken care 
of for you in the code.

Original comment by jcgregorio@google.com on 4 Sep 2012 at 1:30

GoogleCodeExporter commented 9 years ago
I'm using the python client library for some tasks. For this particular task, I 
use the Velruse library https://github.com/bbangert/velruse with this 
implementation of Google OAuth2 
https://github.com/naktinis/velruse/blob/master/velruse/providers/google2.py.

Here's a simple scenario that breaks:
1. User authorizes access (I get access_token + refresh_token).
2. User asks us to remove her credentials from DB (we no longer have her 
access_token nor refresh_token). However, the token is NOT revoked on Google 
side.
3. User authorizes again (with approval_prompt=auto) - I get a new 
access_token, but no refresh token.

Is this documented anywhere in Google OAuth2 implementation docs or OAuth 2 
specs? I want to be able to let the user remove her keys from our DB, so that 
it would still let the user change her mind without revoking the token via 
Google.

Original comment by nakti...@gmail.com on 4 Sep 2012 at 1:44

GoogleCodeExporter commented 9 years ago
You only get the refresh token the first time and you will have to reprompt to 
get it again.

From https://developers.google.com/accounts/docs/OAuth2WebServer#offline

Important: When your application receives a refresh token, it is important to 
store that refresh token for future use. If your application loses the refresh 
token, it will have to re-prompt the user for consent before obtaining another 
refresh token. If you need to re-prompt the user for consent, include the 
approval_prompt parameter in the authorization code request, and set the value 
to force.

Original comment by afs...@google.com on 4 Sep 2012 at 1:45

GoogleCodeExporter commented 9 years ago
You should revoke the token programatically:

   https://developers.google.com/accounts/docs/OAuth2WebServer#tokenrevoke

This currently isn't done as part of the python client library, but it's a 
known feature request:

  http://code.google.com/p/google-api-python-client/issues/detail?id=98

Original comment by jcgregorio@google.com on 4 Sep 2012 at 2:13

GoogleCodeExporter commented 9 years ago
Thanks for the explanation. In this case, the token revocation method in python 
client would indeed be useful.

I would also suggest elaborating on the "refresh_token" explanation in 
https://developers.google.com/accounts/docs/OAuth2WebServer#handlingtheresponse.
 Currently it says:
"""
A token that may be used to obtain a new access token. Refresh tokens are valid 
until the user revokes access. This field is only present if 
access_type=offline is included in the authorization code request.
"""

It could also mention when refresh_token will NOT be present. Because after 
reading this I expected that it will ALWAYS be present when access_type=offline 
is included - which is not the case.

Original comment by nakti...@gmail.com on 4 Sep 2012 at 3:30

GoogleCodeExporter commented 9 years ago

Original comment by jcgregorio@google.com on 10 Dec 2012 at 1:35