使用 Python gdata 和 oAuth 2 对日历进行身份验证

发布于 2024-12-01 15:21:28 字数 1866 浏览 2 评论 0原文

我正在将一个 Python 应用程序从 oAuth 1 迁移到 oAuth 2,该应用程序读取用户的 Google 日历提要。

  • 使用 oAuth 1: 如果用户可以使用他的 GMail 进行身份验证,我的应用程序将打开浏览器 帐户并授权访问,我的应用程序将获得 user_token, 该用户的 user_secret,然后向日历源进行身份验证:

    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)
    

此令牌、秘密对将长期有效。

此 access_token 是短暂的。

我对这里发布的代码进行了一些操作 http://codereview.appspot.com/4440067/ 并且工作正常。

我的问题:

-我通过我的curl调用获取access_token、refresh_token 应用程序,我可以成功检索两者。但是,当我将其应用到 这段代码:

    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)

它给了我:

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

-假设我可以成功执行上述操作,我可以将访问/刷新令牌保存在数据库中。使用python gdata lib,如何使用refresh_token请求另一个access_token(因此不必每次使用应用程序时都询问用户授权访问它)

提前非常感谢!

中号

I'm migrating a Python application from oAuth 1 to oAuth 2 that reads a user's Google
calendar feed.

  • With oAuth 1:
    My app would open a browser were user can authenticate with his GMail
    account and authorize access, and my app would obtain a user_token,
    user_secret for that user, then authenticate to 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 would be long lived.

This access_token is short lived.

I played a little bit with the code posted here http://codereview.appspot.com/4440067/
and works ok.

My questions:

-I am obtaining access_token, refresh_token via a curl call from my
app, and I can successfully retrieve 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)

It 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

-Assuming I can successfully do the above, I can save the access/refresh tokens in a DB. Using python gdata lib, how can I use refresh_token to request another access_token (hence not having to ask the user every time they use the app to authorize access to it)

Thanks much in advance!

M

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

从此见与不见 2024-12-08 15:21:28

Marchie,

我没有看到您其余的堆栈跟踪,但可以给出三个特定问题以及相应的解决方案,以解决您的整体问题。

问题 I:未在对象上设置值 redirect_uri

请注意如何在 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
  })

这取决于在对象上将 redirect_uri 属性设置为最初在 generate_authorize_url< 中设置的值/代码>。因此,通过调用重建令牌后,

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

您只需设置重定向 URI:

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

问题 IIredirect_uri 的默认值不正确(更具体地说,已弃用)。

由于您调用不带参数的 generate_authorize_url,因此使用了 redirect_uri 的默认值,当前为 oob。根据 OAuth 2.0 文档 的规定,oob 为不在受支持的值之列(已被弃用)。

如果您确实使用已安装的应用程序,则需要将其设置为

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

此外,当您调用 generate_authorize_url 来获取初始令牌时,您需要将其用作关键字参数

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

问题 III:您使用错误的值(也是尚未在代码片段中实例化的值)调用 get_access_token

您应该使用授权后收到的代码的字符串值或使用以 'code' 作为键的字典来调用此函数。

这可以通过以下方式完成:

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)

帖子脚本补丁 还发布了博客发布关于使用该补丁的文章。 (请注意,在 generate_authorize_url 函数中使用关键字 redirect_url 而不是 redirect_uri 时,帖子中存在拼写错误。)

Marchie,

I don't see the rest of your stack trace, but can give three particular issues with corresponding solutions that will solve your overall problem.

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

Note how the body of the request 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 being set on the object to the value that was originally set in generate_authorize_url. So, after reconstructing the token by calling

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

you will simply 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 was used, which is currently oob. As the OAuth 2.0 docs state, the oob is not among the supported values (it has been deprecated).

If you are indeed using an Installed Application, you will need to instead set it to

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

In addition, 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 are calling get_access_token with the incorrect value (also one that hasn't been instantiated in your code snippet).

You should either call this with a string value of the code you receive after authorizing or with a dictionary that has 'code' as a key.

This can be done via the following:

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 author of the patch also published a blog post on using the patch. (Note there is a typo in the post when the keyword redirect_url is used instead of redirect_uri in the generate_authorize_url function.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文