connect-mongo 创建的条目未过期

Posted

技术标签:

【中文标题】connect-mongo 创建的条目未过期【英文标题】:Entries created by connect-mongo not being expired 【发布时间】:2014-03-12 21:12:38 【问题描述】:

我有一个使用 Express 设置的节点服务器,使用 Passport 进行身份验证。我听说 connect-mongo 很适合用于持久登录会话,所以我设置了它,一开始一切似乎都很好,mongo 根据过期时间自动删除用户会话。但是,在生产中,对于每个用户会话,还有 5000 个其他永不过期的空会话,我无法弄清楚为什么 mongo 不会自动清理这些会话。 mongo 中空会话的示例条目如下所示:

 "_id" : "JMtV5Z1oWRkgh9KIKlwSqwOE",
  "session" : "\"cookie\":\"originalMaxAge\":86400000,\"expires\":\"2014-02-13T22:09:09.948Z\",\"httpOnly\":true,\"path\":\"/\",\"passport\":",
  "expires" : Date( 1392329349948 ) 

这里是 Express 配置代码:

var express = require('express')
  , passport = require('passport')
  , fs = require('fs')
  , http = require('http')
  , https = require('https')
  , util = require('util')
  , mongoose = require('mongoose')
  , MongoStore = require('connect-mongo')(express)
  , FacebookStrategy = require('passport-facebook').Strategy
  , LocalStrategy = require('passport-local').Strategy;


app.configure(function() 
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.logger());
  app.use(requireHTTPS);
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.session( 
    secret: 'asdfasdf',
    cookie:  maxAge: 24 * 60 * 60 * 1000 ,
    store: new MongoStore(
        mongoose_connection: mongoose.connections[0],
        clear_interval: 3600
      , function(err)
        console.log(err || 'connect-mongodb setup ok');
      
    )
  ));

  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'),  maxAge: 31557600000 );
);

我认为这些空会话是由搜索机器人创建的,因为我想不出我的网站会在一夜之间被点击 20,000 次的任何其他原因。但即便如此,只要会话正确过期就不会出现问题,而且我的数据库不会耗尽内存,但它们永远不会被清理。

任何见解将不胜感激,谢谢

【问题讨论】:

您能否使用mongo 命令行工具,选择用于会话的数据库(可能仅称为sessions),然后在现有集合上运行:db.collectionName.getIndexes() 并在您的问题中显示它?因为应该有索引来确保 mongo 根据索引字段过期记录。 【参考方案1】:

connect-mongo 似乎工作正常。您将 maxAge 设置为 1000 天,这就是存储在 cookie 中的内容。见 ttl 信息here。

我怀疑您的问题是您实际上只希望在用户登录时发布 cookie,而不是针对任何资产(页面、图像、javascript 等)的每个请求。在这种情况下,您可以在 express.cookieParser 和 express.session 前面添加一个可选的第一个参数,以便该中间件仅在某些路径上运行(例如,/login)。

或者,您可以将您的 express.static 中间件移到 express.cookieParser 之上,然后不会为静态资产发出 cookie。

【讨论】:

【参考方案2】:

阅读文档here

删除过期会话

connect-mongo 使用 MongoDB 的 TTL 收集功能 (2.2+) mongod 自动删除过期会话。 (mongod 运行此检查 每分钟。)

注意:通过 connect/express 的默认设置,会话 cookie 设置为过期 当用户关闭浏览器时(maxAge: null)。依据 标准行业惯例,connect-mongo 会将这些会话设置为 从他们的最后一个“集合”到期两周。您可以覆盖此行为 通过手动设置您的 cookie 的 maxAge - 请记住 任何小于 60 秒的值都是没有意义的,因为 mongod 只会 每分钟删除 TTL 集合中的过期文档。

更多信息,请咨询connect的session documentation

cookie:  maxAge: 24 * 60 * 60 * 1000 

您将 cookie 的过期时间设置为 1000 天,因此会话没有得到 已到期。您可以将其设置为较低的值,例如一两天。

【讨论】:

以上是关于connect-mongo 创建的条目未过期的主要内容,如果未能解决你的问题,请参考以下文章

Spring Redis - 主条目过期后未删除索引

Laravel 6 会话和 CSRF Coo​​kie 未设置——每次页面加载的会话数据库中的新条目

如何在 connect-mongo 中使用会话?

iPhone Developer' 不匹配任何有效的、未过期的证书/私钥对 - 但我正在创建和 Ipad 应用程序 [重复]

使用 connect-mongo 时处理数据库错误

使用 connect-mongo 时处理数据库错误