Oauth + Aeoid + Python + 谷歌应用引擎 + 谷歌文档
我正在为学校报纸开发一个故事分配系统,使用的是Google App Engine。这个系统可以跟踪写作的截止日期,让作者选择故事,并提供一周故事的“快速浏览”视图。我的搭档和我希望将它与我们报纸的Google Apps完全整合。而且,由于我们没有Google Apps Premier,所以必须使用三方OAuth。
在这个过程中,我发现了Aeoid,并按照说明成功实现了联合登录。这真是太酷了!
我现在遇到的问题是,使用OAuth获取用户的Google文档列表。我在这里设置了一个测试页面:mustrun.cornellsun.com/test。它给我报错了——我把错误信息复制在了邮件底部。我不确定这是否与我的消费者密钥有关(我应该使用从Google市场获得的密钥吗?还是应该使用从管理域页面获得的密钥?)。现在我使用的是从管理域页面获得的密钥。
更复杂的是,实际的appspot域名是mustrun2sun[].appspot[太新了,不能发多个链接].com,但我在Google Apps中设置了只有我的域名用户可以登录,并且应用程序部署在我的域名上。(应用程序部署为must[]run[].corn[]ellsun[].[]com
,所有地方都这样引用,包括管理域的地方。)
我使用的是GDClient 2.0类,所以我相当确定一切应该按计划工作……也就是说,我没有使用旧的服务或其他东西。我用htt[]p:/[]/k[]ing[]yo-bachi.blog[]spot.c[]om/2010/05/gaego[]ogleoauth.ht[]ml
作为我的OAuth“舞步”的模板,因为Google的示例已经过时,使用的是旧的Google数据1.0库——我想是这样。
当我访问我的测试页面时,出现的错误是
Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 511, in __call__
handler.get(*groups)
File "/base/data/home/apps/mustrun2sun/1.341947133742569880/main.py", line 170, in get
feed = client.GetDocList(auth_token=gdata.gauth.AeLoad(users.get_current_user().user_id())) #auth_token=TOKEN
File "/base/data/home/apps/mustrun2sun/1.341947133742569880/gdata/docs/client.py", line 141, in get_doclist
auth_token=auth_token, **kwargs)
File "/base/data/home/apps/mustrun2sun/1.341947133742569880/gdata/client.py", line 635, in get_feed
**kwargs)
File "/base/data/home/apps/mustrun2sun/1.341947133742569880/gdata/client.py", line 308, in request
response, Unauthorized)
Unauthorized: Unauthorized - Server responded with: 401, <HTML>
<HEAD>
<TITLE>Token invalid - Invalid AuthSub token.</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Token invalid - Invalid AuthSub token.</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
另外,由于没有源代码,这里是相关的代码:
import gdata.auth
import gdata.gauth
import gdata.docs.client
import gdata.docs.data
import gdata.docs.service
import gdata.alt.appengine
from aeoid import middleware, users
class GetOauthToken(webapp.RequestHandler):
def get(self):
user_id = users.get_current_user().user_id()
saved_request_token = gdata.gauth.AeLoad("tmp_"+user_id)
gdata.gauth.AeDelete ("tmp_" + user_id)
request_token = gdata.gauth.AuthorizeRequestToken(saved_request_token, self.request.uri)
#upgrade the token
access_token = client.GetAccessToken(request_token)
#save the upgraded token
gdata.gauth.AeSave(access_token, user_id)
self.redirect('/test')
class Test(webapp.RequestHandler):
def get(self):
TOKEN = gdata.gauth.AeLoad(users.get_current_user().user_id())
if TOKEN:
client = gdata.docs.client.DocsClient(source=SETTINGS['APP_NAME'])
client.auth_token = gdata.gauth.AeLoad(users.get_current_user().user_id()) #could try to put back as TOKEN?
self.response.out.write('moo baby')
client.ssl = True
feed = client.GetDocList(auth_token=gdata.gauth.AeLoad(users.get_current_user().user_id())) #auth_token=TOKEN
self.response.out.write(feed)
self.response.out.write('moo boobob')
self.response.headers['Content-Type'] = 'text/plain'
for entry in feed.entry:
self.response.out.writeln(entry.title.text)
else:
# Get unauthorized request token
gdata.gauth.AeDelete(users.get_current_user().user_id())
client = gdata.docs.client.DocsClient(source=SETTINGS['APP_NAME'])
client.ssl = True # Force communication through HTTPS
oauth_callback_url = ('http://%s/get_oauth_token' %
self.request.host)
request_token = client.GetOAuthToken(
SETTINGS['SCOPES'], oauth_callback_url, SETTINGS['CONSUMER_KEY'],
consumer_secret=SETTINGS['CONSUMER_SECRET'])
gdata.gauth.AeSave(request_token, "tmp_"+users.get_current_user().user_id())
# Authorize request token
domain = None#'cornellsun.com'
self.redirect(str(request_token.generate_authorization_url(google_apps_domain=domain)))
我在网上到处寻找答案,但一直没有找到。
3 个回答
我个人没有使用过OAuth,但我注意到了一些可能对你有帮助的事情:
401错误很可能是HTTP 401错误,这意味着网址是有效的,但需要身份验证。这显然是因为OAuth尝试失败导致的,但也可能很重要的是,要把没有登录的用户重定向到另一个页面。
错误发生在你给feed变量赋值的时候。auth_token参数是不是应该只是一个用户名呢?
3.你在使用这行代码。
gdata.gauth.AeLoad(users.get_current_user().user_id())
很频繁。虽然这可能和你的身份验证问题无关,但你最好只查询一次,然后把结果存储在一个变量里。下次需要的时候就直接用这个变量。这样可以提高你应用的速度。
再次抱歉,我没有具体的OAuth经验。我只是试着找一些可能能帮助你走上正确道路的东西。
我刚刚花了几个小时才发现,如果网址不正确,也会出现401错误。
在我的例子中,我做的是
.../buzz/v1/activities/@me/@self**?&**alt=json
而不是
.../buzz/v1/activities/@me/@self**?**alt=json
我有一个可以正常运行的Python应用程序,使用了OpenID和OAuth来获取你的Google联系人:
http://github.com/sje397/Chess
这个应用程序可以在这里访问:
需要注意的是,现在不再需要Aeoid,因为App Engine已经支持内置的OpenID功能。