我是Tornado的新手并尝试使用简单的OAuth twitter身份验证。根据文档,我需要设置一个身份验证处理程序,如下所示:
class TwitterAuthHandler(BaseHandler, tornado.auth.TwitterMixin):
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self):
if self.get_argument("oauth_token", None):
user = yield self.get_authenticated_user()
if not user:
raise tornado.web.HTTPError(500, "Twitter auth failed")
self.set_secure_cookie("twitter_user", user)
self.redirect("/")
else:
self.authenticate_redirect()
然而,当我运行此代码时,我收到错误:
File "/Library/Python/2.7/site-packages/tornado/web.py", line 485, in redirect
raise Exception("Cannot redirect after headers have been written")
Exception: Cannot redirect after headers have been written
这似乎是因为异步调用运行不正常,self.authenticate_redirect()
行引发了异常。如果我将@tornado.gen.coroutine
替换为@tornado.gen.engine
,一切正常。但是,我知道gen.engine
是旧的做事方式,gen.coroutine
应该是首选,因为它会返回未来。
我还尝试将电话打包到self.get_authenticated_user()
中的tornado.gen.Task()
。我不确定何时需要使用gen.Task()
进行换行,但这种情况似乎没有任何区别。
此代码有什么问题,为什么gen.coroutine
失败但gen.engine
有效?
答案 0 :(得分:3)
检查完之后,我认为这可能是一个错误。将示例代码发布到python-tornado Google Group的这个主题中:https://groups.google.com/forum/?fromgroups#!topic/python-tornado/YypdSaXsM_Y确认了它:
auth * _redirect方法不返回Futures,因此它们不能 屈服了,但他们应该。作为现在的解决方法,您可以继续 使用@ gen.engine并在不屈服的情况下调用这些方法。