Calendar Authentication Using Python gdata and oAuth 2

I am migrating a Python application from oAuth 1 to oAuth 2 that reads a Google user calendar channel.

  • From oAuth 1: My application will open a browser if the user can authenticate using their GMail account and access authorization, and my application will receive user_token, user_secret for this user, then authenticate in the calendar feed:

    client = gdata.calendar.client.CalendarClient(source='test') client.auth_token = gdata.gauth.OAuthHmacToken(app_key, app_secret,user_token,user_secret,gdata.gauth.ACCESS_TOKEN) 

This token, secret pair is durable.

This access_token is short-lived.

I played around a bit with the code posted here http://codereview.appspot.com/4440067/ and it works fine.

My questions:

-I get access_token, refresh_token through a curl call from my application, and I can successfully extract both. However, when I apply it to this code:

  token = gdata.gauth.OAuth2Token(client_id=client_id,client_secret=client_secret', scope='https://www.google.com/calendar/ feeds',user_agent='calendar-cmdline-sample/1.0') uri = token.generate_authorize_url() token.get_access_token(access_token) 

This gives me:

 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Python/2.6/site-packages/gdata/gauth.py", line 1267, in get_access_token raise OAuth2AccessTokenError(error_msg) gdata.gauth.OAuth2AccessTokenError 

-Luck I can successfully complete the above, I can save access / update tokens in the database. Using python gdata lib, how can I use refresh_token to request another access_token (from here I don’t need to ask the user every time they use the application to authorize access to it).

Thank you very much!

M

+4
source share
1 answer

Marchie,

I don’t see the rest of the stack trace, but I can give you three specific problems with corresponding solutions that will help solve your general problem.

Problem I : The value of redirect_uri not set on the object.

Notice how the request body is specified in get_access_token :

 body = urllib.urlencode({ 'grant_type': 'authorization_code', 'client_id': self.client_id, 'client_secret': self.client_secret, 'code': code, 'redirect_uri': self.redirect_uri, 'scope': self.scope }) 

This depends on the redirect_uri property set on the object for the value that was originally set to generate_authorize_url . So, after recovering the token, calling

 token = gdata.gauth.OAuth2Token(...) 

you just need to set the redirect URI:

 token.redirect_uri = 'http://path/that/you/set' 

Problem II : The default value of redirect_uri is incorrect (more specifically, deprecated).

Since you called generate_authorize_url with no arguments, the default value for redirect_uri , which is currently oob , was oob . Since OAuth 2.0 docs , oob not among the supported values ​​(it is deprecated).

If you really use the installed application, you will need to install it

 token.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob' 

Also, when you call generate_authorize_url to get the initial token, you will need to use this as a keyword parameter

 url = token.generate_authorize_url(redirect_uri='urn:ietf:wg:oauth:2.0:oob') 

Problem III . You call get_access_token with the wrong value (also the one that was not created in the code snippet).

You should either call it the string value of the code that you receive after authorization, or with a dictionary with 'code' as the key.

This can be done as follows:

 import atom.http_core # Page the user is redirected to after authorizing redirected_page = 'http://path/that/you/set?code=RANDOM-CODE' uri = atom.http_core.ParseUri(redirected_page) # uri.query is a dictionary with the query string as key, value pairs token.get_access_token(uri.query) 

Post Script . The patch author also posted a blog post about using the patch. (Note that there is a typo in the column when <> redirect_url used instead of redirect_url ).

+1
source

Source: https://habr.com/ru/post/1369086/


All Articles