在Tornado中处理用户会话的标准方法
为了避免“没有最佳答案”的问题,我想问一下,在使用Tornado框架时,处理会话的标准或最常见的方法是什么。也就是说,如果我们不使用第三方认证(比如OAuth等),而是想要自己建立一个用户表,并在浏览器中使用安全的cookie,同时大部分会话信息存储在服务器上,那么最常见的做法是什么呢?我看到有些人使用Redis,有些人使用他们的普通数据库(MySQL、Postgres等),还有些人使用memcached。
我正在开发的应用程序不会同时有数百万用户,甚至可能连几千个都没有。不过,最终它需要实现一些中等复杂的授权方案。我想确保我们不会做一些“奇怪”的事情,走上与Tornado社区的主流不同的道路,因为虽然认证和授权是我们需要的,但并不是我们产品的核心,所以这不是我们应该区分自己的地方。因此,我们希望了解大多数使用Tornado的人在这方面是怎么做的,所以我认为这个问题在理论上是有一个客观正确答案的。
理想的答案当然会指向一些示例代码。
4 个回答
关于会话(sessions),最关键的问题不是把它们存在哪里,而是如何聪明地让它们过期。无论会话存储在哪里,只要存储的会话数量合理(也就是说,只存活跃的会话和一些备用的),这些数据都能放进内存里,访问速度会很快。如果存了很多过期的无用数据,你可能会遇到不可预测的延迟(因为需要从硬盘读取会话数据)。
下面是一些其他微框架(比如CherryPy和Flask)处理会话的方式:
- 首先,创建一个表格来存储
session_id
和你想要跟踪的其他信息。某些框架允许你将这些信息按用户存储在文件中,或者直接存储在内存里。如果你的应用比较小,可以考虑这些选项,但使用数据库通常会更简单。 - 当收到请求时(我想是
RequestHandler initialize()
函数?),如果没有session_id
的cookie,就用随机生成器设置一个安全的会话ID。我对Tornado的经验不多,但看起来设置一个安全的cookie会很有用。把这个session_id
和相关信息存储在你的会话表中。要注意的是,每个用户都会有一个会话,即使他们没有登录。当用户登录时,你需要把他们的登录状态(以及用户名、用户ID等)附加到他们的会话中。 - 在你的
RequestHandler
初始化函数中,如果有session_id
的cookie,就从数据库中读取所需的会话信息,可能还需要创建一个自己的会话对象来填充并作为该请求处理器的成员变量进行存储。
记住,会话应该在一段时间不活动后过期,所以你也需要检查这一点。如果你想要一种“记住我”的登录方式,就需要使用安全的cookie来表示这一点(可以在OWASP上了解更多,确保尽可能安全,另外,Tornado的secure_cookie可能会对此有所帮助)。当收到一个超时的会话时,你可以通过创建一个新会话并将旧会话中的相关信息转移到新会话中来重新认证新用户。
Tornado 是一个设计为无状态的框架,默认情况下不支持会话管理。
可以使用安全的 cookies 来存储一些敏感信息,比如用户的 ID。对于不那么重要的信息,可以使用普通的 cookies。
如果需要存储大对象,建议使用标准的方案,比如 MySQL 加上 memcache。