问题描述
我正在将Python应用程序从oAuth 1迁移到可读取用户Google的oAuth 2日历供稿.
I'm migrating a Python application from oAuth 1 to oAuth 2 that reads a user's Googlecalendar feed.
-
使用oAuth 1:如果用户可以通过其GMail进行身份验证,则我的应用程序将打开浏览器帐户并授权访问权限,我的应用程序将获得一个user_token,该用户的user_secret,然后验证日历供稿:
With oAuth 1:My app would open a browser were user can authenticate with his GMailaccount 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.
- 使用oAuth 2:我在Google API控制台中注册了我的应用,并获得了oAuth 2client_id和client_secret,并修改了应用程序以请求用户的access_token,刷新令牌,来自 https://accounts.google.com/o/oauth2/token对于GData库,我应用了在此处指定的gauth.py补丁: http://codereview.appspot.com/4440067/
- With oAuth 2:I registered my app in the Google API console and obtained the oAuth 2client_id and client_secret, and modified the app to request theuser's access_token, refresh_token from https://accounts.google.com/o/oauth2/tokenFor the GData lib, I applied the gauth.py patch specified here:http://codereview.appspot.com/4440067/
此访问令牌是短暂的.
我使用了此处发布的代码 http://codereview.appspot.com/4440067/一切正常.
I played a little bit with the code posted here http://codereview.appspot.com/4440067/and works ok.
我的问题:
-我正在通过我的curl调用获取access_token,refresh_token应用程序,我可以成功检索到两者.但是,当我将其应用于这段代码:
-I am obtaining access_token, refresh_token via a curl call from myapp, and I can successfully retrieve both. However, when I apply it tothis 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)
它给了我
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(因此,不必在用户每次使用该应用授权访问它时都询问用户)
-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)
非常感谢!
M
推荐答案
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.
问题I :未在对象上设置值redirect_uri
.
Problem I: The value redirect_uri
is not set on the object.
请注意如何在get_access_token
中指定请求的正文:
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
})
这取决于在对象上将redirect_uri
属性设置为最初在generate_authorize_url
中设置的值.因此,在通过调用
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(...)
您只需要设置重定向URI:
you will simply need to set the redirect URI:
token.redirect_uri = 'http://path/that/you/set'
问题II :redirect_uri
的默认值不正确(更具体地说,已弃用).
Problem II: The default value of redirect_uri
is incorrect (more specifically, deprecated).
由于您不带任何参数调用了generate_authorize_url
,因此使用了redirect_uri
的默认值,当前值为oob
.由于 OAuth 2.0文档状态,oob
不在受支持的值中(已弃用).
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'
此外,当您调用generate_authorize_url
获取初始令牌时,需要将其用作关键字参数
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')
问题III :您正在使用错误的值(也是未在代码段中实例化的值)调用get_access_token
.
Problem III: You are calling get_access_token
with the incorrect value (also one that hasn't been instantiated in your code snippet).
您应该使用授权后收到的代码的字符串值或使用以'code'
作为键的字典来调用它.
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)
后继脚本:补丁的作者还发布了博客文章. (请注意,使用关键字redirect_url
代替generate_authorize_url
函数中的redirect_uri
时,文章中有错别字.)
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.)
这篇关于使用Python gdata和oAuth 2对日历进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!