[英]How to store database session in Tornado RequestHandler
我正在Tornado中实现用于用户会话管理的安全cookie方案。 用户的详细信息可通过SQLAlchemy访问。 当前,我需要打开两个数据库会话:一个用于验证用户在身份验证期间是否存在,另一个用于查询模型的其他部分。 像这样:
class BaseHandler(tornado.web.RequestHandler):
def get_current_user(self):
user_id = self.get_secure_cookie('user')
if not user_id:
return None
with model.session_scope() as session:
user = session.query(model.AppUser).get(user_id)
if not user:
return None
session.expunge(user)
return user
class OtherHandler(BaseHandler):
@tornado.web.authenticated
@gen.coroutine
def put(self, ob_id):
with model.session_scope() as session:
other = session.query(model.Other).get(ob_id)
session.merge(self.current_user)
if not user.can_view(other):
raise AuthzError
yield self.some_operation(other)
self.finish()
如果我不必使用merge
将用户对象带回到会话中,那就太好了。 有没有安全的方法将数据库会话和持久性 user
对象存储在处理程序中? 我正在考虑做这样的事情:
class BaseHandler(tornado.web.RequestHandler):
def prepare(self):
self.session = model.Session()
user_id = self.get_secure_cookie('user')
if user_id:
self.current_user = session.query(model.AppUser).get(user_id)
def finish(self, chunk=None):
try:
return super().finish(chunk)
finally:
self.session.commit()
def send_error(self, status_code=500, **kwargs):
try:
return super().send_error(status_code=status_code, **kwargs)
finally:
self.session.rollback()
问题:
session
(或其他任何东西)在self
使用异步代码(时,即使@gen.coroutine
和yield
)? finish
和send_error
关闭会话的方式是否可靠 ? 我想确保我没有任何僵尸会议。 我在finish和send_error中关闭会话的方式是否可靠? 我想确保我没有任何僵尸会议
您可以使用on_finish
或on_connection_close
。
def on_finish(self):
if self.get_status_code() >= 500:
self.session.rollback()
else:
self.session.commit()
请注意,可能存在区分错误响应的更好方法。 还可以看看讨论-https: //github.com/tornadoweb/tornado/issues/517
即使使用异步代码(@ gen.coroutine和yield),将会话(或其他任何内容)自身存储起来是否安全?
为每个请求创建RequestHandler
对象,但不共享该对象。 在这种情况下,异步不会使代码更容易(我认为)将数据存储在“ self
”中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.