Node Express Connect - 会话管理

ski*_*joe 8 session connect node.js express arangodb

我为ArangoDB for ConnectJS编写了一个会话存储驱动程序.它工作,虽然仍然非常alpha,但我有几个问题.

具有expires属性"false"的第一个会话仅在用户代理的持续时间内保留.我注意到,当浏览器窗口关闭时,不会调用session.destroy().这导致在商店中留下"被放弃的"会话.我怎样才能有效地清除这些?有没有办法按计划搜索和销毁被遗弃的会话?

其次,我已经实现了本页所述的会话商店的最低要求:http://www.senchalabs.org/connect/session.html(接近底部)

那将是获取,设置和破坏.另外两种推荐的方法是长度和清晰.这些方法究竟应该做什么?我假设长度返回会话活动的时间长度?"清除"与摧毁有什么不同?谢谢!

bar*_*son 6

除非您在客户端上绑定某个事件以通知服务器窗口正在关闭,否则服务器将无法知道该会话已不再使用.

您希望在心理上将会话视为两个部分.一部分是在节点和浏览器之间传递的令牌(cookie).第二个是商店中会话的实际持久性(基本的MemoryStore或Redis,或者另一个数据库的新会话存储).所有连接会话代码正在进行的是将它们与每个请求进行匹配.

  • 检查会话cookie
  • 如果存在,请尝试在商店中查找
  • 使存储中检索到的数据可用于请求
  • 在请求结束时,更新cookie的TTL信息
  • 将会话写回商店

请注意,除非您使用MemoryStore,否则节点在内存中没有会话数据,除非您的请求在其上运行.(好吧,它会在内存中存在一段时间,但会被取消引用并受到垃圾收集).当您考虑各种部署方案时,这是有道理的.

因此,会话服务器端到期的工作属于商店本身.其中一个原因Redis的是伟大的,这是因为它管理automatagically到期的事情,你可以看到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);
    } 
  };
Run Code Online (Sandbox Code Playgroud)

你可以看到它将TTL除以1000,因为它的使用时间为秒而不是毫秒.在最流行的MongoDB的会话存储使用同样的方式MongoDB的TTL功能.

所以这是一个很长的路要说,你要么依靠你的数据库引擎自动提供服务器端的会话过期,要么你自己需要实现过期.您可以在节点应用程序之外(可能是另一个节点进程)执行此过程,或者您的商店实现可以安装SetInterval任务以定期检查和清除它.例如,基于MySQL的会话存储就是这样做的

关于你问题的第二部分,做什么lengthclear做什么?评论者是正确的,RedisStore没有实现这些并且它们可能被安全地忽略,但是你可以在MemoryStore源代码中看到它们的实现.不太令人兴奋.

clear 如果提供回调,则清空所有会话和回调:

MemoryStore.prototype.clear = function(fn){
  this.sessions = {};
  fn && fn();
};
Run Code Online (Sandbox Code Playgroud)

length 只需回调商店中的会话数量:

MemoryStore.prototype.length = function(fn){
  fn(null, Object.keys(this.sessions).length);
};
Run Code Online (Sandbox Code Playgroud)

希望这有用.