1

我是 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()in tornado.gen.Task()。我不确定何时gen.Task()需要使用包装,但这在这种情况下似乎没有任何区别。

这段代码有什么问题,为什么gen.coroutine失败但gen.engine有效?

4

1 回答 1

3

检查后我认为这可能是一个错误。将示例代码发布到 python-tornado Google Group 的这个线程中:https ://groups.google.com/forum/?fromgroups#!topic/python-tornado/YypdSaXsM_Y证实了这一点:

auth*_redirect 方法不返回 Futures,因此它们不能被产生,但它们应该。作为现在的解决方法,您可以继续使用 @gen.engine 并调用这些方法而不让步。

于 2013-05-29T15:27:32.977 回答