问题描述
有一些子类继承ManageHandler
,每个子类都需要做私有检查.因此,我编写了 private_auth
并让它在 __init__
中进行私有检查,并在 GET/POST 方法之前调用它.
There a some subclass inheritance ManageHandler
, and each sub class need to do private check.So, I write private_auth
and let it to do the private check in the __init__
, and call it before the GET/POST method.
如果私人检查失败,只返回 404 错误.但是,它不起作用.那么如何停止请求并返回错误页面?
If failed the private check, just return 404 error. However, it not work. So how to stop the request and return the error page?
我的代码贴在下面:
class ManageHandler(BaseHandler):
def __init__(self, *argc, **argkw):
super(ManageHandler, self).__init__(*argc, **argkw)
self.private_auth()
def private_auth(self):
self.user = self.get_secure_cookie("user")
self.private = self.UserModel.get_user_level_by_name(self.user)
#not login
if self.private == -1:
return
if self.private != 4:
self.render("404.html")
self.finish()
@tornado.web.authenticated
def get(self, argkw={}):
pass
Tornado 报告此错误.
Tornado report this error.
[E 140321 02:06:04 iostream:357] Uncaught exception, closing connection.
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/tornado/iostream.py", line 354, in wrapper
callback(*args)
File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 331, in wrapped
raise_exc_info(exc)
File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "/Library/Python/2.7/site-packages/tornado/httpserver.py", line 328, in _on_headers
self.request_callback(self._request)
File "/Library/Python/2.7/site-packages/tornado/web.py", line 1651, in __call__
handler = spec.handler_class(self, request, **spec.kwargs)
File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 23, in __init__
self.private_auth()
File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 36, in private_auth
self.finish()
File "/Library/Python/2.7/site-packages/tornado/web.py", line 837, in finish
self.flush(include_footers=True)
File "/Library/Python/2.7/site-packages/tornado/web.py", line 784, in flush
for transform in self._transforms:
TypeError: 'NoneType' object is not iterable
[E 140321 02:06:04 ioloop:491] Exception in callback <functools.partial object at 0x10c63e1b0>
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/tornado/ioloop.py", line 477, in _run_callback
callback()
File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 331, in wrapped
raise_exc_info(exc)
File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "/Library/Python/2.7/site-packages/tornado/iostream.py", line 354, in wrapper
callback(*args)
File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 331, in wrapped
raise_exc_info(exc)
File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "/Library/Python/2.7/site-packages/tornado/httpserver.py", line 328, in _on_headers
self.request_callback(self._request)
File "/Library/Python/2.7/site-packages/tornado/web.py", line 1651, in __call__
handler = spec.handler_class(self, request, **spec.kwargs)
File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 23, in __init__
self.private_auth()
File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 36, in private_auth
self.finish()
File "/Library/Python/2.7/site-packages/tornado/web.py", line 837, in finish
self.flush(include_footers=True)
File "/Library/Python/2.7/site-packages/tornado/web.py", line 784, in flush
for transform in self._transforms:
TypeError: 'NoneType' object is not iterable
推荐答案
Tornado 的设计目的不是在 RequestHandler.__init__
中进行身份验证和其他操作.这就是为什么当您从 __init__
调用 self.finish
时会收到异常的原因:RequestHandler 尚未准备好运行 finish
.
Tornado isn't designed to do authentication and other operations in RequestHandler.__init__
. That's why you get an exception when you call self.finish
from __init__
: the RequestHandler isn't ready to run finish
yet.
相反,覆盖 get_current_user()
.基本说明在这里:
Instead, override get_current_user()
. The basic instructions are here:
http://tornado.readthedocs.org/en/latest/web.html#tornado.web.RequestHandler.get_current_user
这里有一个例子:
http://technobeans.wordpress.com/2012/08/14/tornado-authentication/
在你的get_current_user()
中,不要设置self.user
和self.private
,只返回一个元组.像这样:
In your get_current_user()
, don't set self.user
and self.private
, just return a tuple. Something like this:
def get_current_user(self):
private = -1
user = self.get_secure_cookie("user")
if user:
private = self.UserModel.get_user_level_by_name(self.user)
return (user, private) if private == 4 else None
Tornado 会处理剩下的事情.在您的 get()
方法中,当前的 (user, private)
元组将在 self.current_user
中设置.
Tornado will handle the rest. In your get()
method, the current (user, private)
tuple will be set in self.current_user
.
这篇关于Tornado 如何停止当前的请求处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!