Node Express Connect - 会话管理

8

我为ConnectJS编写了一个ArangoDB会话存储驱动程序。它正在工作,虽然仍处于alpha阶段,但我有几个问题。

首先,具有“false”到期属性的会话仅在用户代理的持续时间内保留。我注意到当关闭浏览器窗口时,session.destroy()不会被调用。这导致存储中留下了一个“废弃”的会话。如何有效地清除这些内容?是否有一种方法可以按计划搜索和销毁废弃的会话?

其次,我已根据此页面上概述的最低要求实现了我的会话存储:http://www.senchalabs.org/connect/session.html(接近底部)

那就是获取、设置和销毁。另外两种推荐的方法是长度和清除。这些方法应该做什么?我认为长度返回会话已经活动的时间长度?'clear'与'destroy'有什么不同?


我不确定length和clear应该做什么,因为它们在RedisStore连接引用中没有实现,所以我不会担心它们。 - Tim Brown
1个回答

6
除非在客户端上设置了某些事件来通知服务器窗口正在关闭,否则服务器将无法知道会话不再使用。
您需要将会话精神上视为两部分。一部分是令牌(cookie),它在节点和浏览器之间传递。第二部分是将会话实际持久化存储在存储中(基本的MemoryStore或Redis,或者另一个数据库的新会话存储)。所有的连接会话代码所做的就是将其与每个请求进行匹配。
检查会话cookie。 如果存在,则尝试在存储中查找它。 使从存储检索到的数据对请求可用。 在请求结束时,更新cookie的TTL信息。 将会话写回存储。
请注意,除非使用MemoryStore,否则Node在处理请求时以外的时间内并不在内存中存储会话数据。(嗯,它会在内存中存储一段时间,但会被取消引用并且可能会被垃圾回收)。当您考虑各种部署方案时,这很有意义。
因此,服务器端会话过期的工作落在存储本身上。Redis之所以很棒,其中之一原因是因为它可以自动管理过期的内容,您可以在其set操作中看到connect-redis在执行此操作
  RedisStore.prototype.set = function(sid, sess, fn){
    sid = this.prefix + sid;
    try {
      var maxAge = sess.cookie.maxAge
        , ttl = this.ttl
        , sess = JSON.stringify(sess);

      ttl = ttl || ('number' == typeof maxAge
          ? maxAge / 1000 | 0
          : oneDay);

      debug('SETEX "%s" ttl:%s %s', sid, ttl, sess);
      this.client.setex(sid, ttl, sess, function(err){
        err || debug('SETEX complete');
        fn && fn.apply(this, arguments);
      });
    } catch (err) {
      fn && fn(err);
    } 
  };

您可以看到,它将TTL除以1000,因为它使用秒而不是毫秒来设置过期时间。最受欢迎的MongoDB会话存储也是这样使用 MongoDB的TTL功能。
所以,长话短说,您要么依靠您的数据库引擎自动提供服务器端会话过期,要么需要自己实现过期。您可以在节点应用程序之外拥有一个进程(可能是另一个节点进程)来执行此操作,或者您的存储实现可以安装SetInterval任务以定期检查和清理它。例如,基于MySQL的会话存储就是这样做的 关于您问题的第二部分,什么是lengthclear?评论者正确指出RedisStore没有实现这些功能,但是您可以在MemoryStore源代码中看到它们的实现。不太令人兴奋。 clear清空所有会话,并在提供回调时调用回调:
MemoryStore.prototype.clear = function(fn){
  this.sessions = {};
  fn && fn();
};

length方法只是简单地返回存储中会话的数量:

MemoryStore.prototype.length = function(fn){
  fn(null, Object.keys(this.sessions).length);
};

希望这对您有所帮助。

完美地回答了我所有的问题。谢谢! - skinneejoe
@skinneejoe - 很高兴听到这个消息。我很惊讶之前没有注意到这个问题。 - barry-johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接