node.js + express.js:使用 mongodb/mongoose 处理会话

Posted

技术标签:

【中文标题】node.js + express.js:使用 mongodb/mongoose 处理会话【英文标题】:node.js + express.js: session handling with mongodb/mongoose 【发布时间】:2011-10-12 18:59:14 【问题描述】:

现在我将会话数据存储在与 connect(express) 捆绑在一起的“内存存储”中。但我想/必须改变它以进行生产。

应用程序正在使用 mongodb,我安装了 mongoose 来处理所有数据库通信。

例如初始化我的应用后连接到数据库:

var mongo = require('mongoose');
mongo.connect('mongodb://localhost/myDb');
mongo.connection.on('open', function () 
  app.listen(3000);

我找到了 connect-mongodb 模块,但我不知道如何使用 mongoose 来实现它,或者它是否真的可能? 我需要添加这样的内容:

var mongoStore = require('connect-mongodb');
// ...
app.use(express.session(
  secret: 'topsecret',
  maxAge: new Date(Date.now() + 3600000),
  store: new mongoStore( db: 'myDb' )
));

还是我必须直接使用 mongodb 模块再次定义我的数据库连接?

【问题讨论】:

【参考方案1】:

所以connect-mongodb 不使用Mongoose,它使用node-mongodb-native 驱动程序(即: npm install mongodb)。 Mongoose 也依赖于这个驱动,所以它应该存在。

查看the code directly,您必须将数据库连接信息作为MongoStore 对象提供:

store: new mongoStore( host: 'session_server', port: 27017, db: 'seesion', collection: 'sessions' )

通常,您需要一些可以动态加载的“配置”对象或变量(dev vs test vs prod)。然后你将 host/port/db/auth 从该配置对象中拉出。

【讨论】:

你链接到 connect-mongo,我在示例中使用了 connect-mongodb。但它们几乎相同,所以我会检查一下。【参考方案2】:

看起来你可以这样做来设置connect-mongodb,假设你上面的猫鼬连接代码运行得更早:

app.use(express.session(
  secret: 'topsecret',
  maxAge: new Date(Date.now() + 3600000),
  store: new mongoStore( db: mongoose.connections[0].db )
));

【讨论】:

在我连接到数据库之前,我在 app.configure() 中使用 express.session()。我想,我将定义一个包含所有数据库信息的配置对象并尝试使用 connect-mongo(而不是 connect-mongodb) - 实现看起来比 connect-mongodb 更容易 github 页面中的示例没有说明如何与 mongoose 一起使用。这个例子很有帮助。【参考方案3】:

您可以传入连接详细信息(主机、用户名、密码等)的对象。

你也可以传入一个连接 url,比如 mongodb://user:pass@host.com/db_name。

这两种方法都会自动启动一个新的连接,无论您是否已经拥有或将要启动一个 mongoose 连接。

在最新的代码中,您可以将句柄传递给现有连接,即mongodb.Db 的实例。对于猫鼬,这将是mongoose.connection.db。但是,此代码不在实际版本中,当我尝试它时,它不起作用。可能还没有准备好使用(或未经测试)。

我敢肯定,如果您等待下一个版本,您将能够传入现有的 mongoose 连接。同时,您只需要接受两个连接,一个来自 mongoose,一个来自 connect-mongodb。

我从https://github.com/tedeh/connect-mongodb 获得了连接信息,并通过查看源代码 (relevant commit) 获得了句柄信息。

【讨论】:

【参考方案4】:

最后,我使用了之前给出的每个答案:

我从 connect-mongodb 切换到 connect-mongo 模块 我正在使用通用 conf 对象来存储我的配置数据 有两个 db 连接,因为它对我来说更容易处理(以后可能会更改,如果/当新版本的 mongoose/express 出现时)

要求:

var express = require('express'),
    MongoStore = require('connect-mongo')(express),
    mongo = require('mongoose');

配置对象:

var conf = 
  db: 
    db: 'myDb',
    host: '192.168.1.111',
    port: 6646,  // optional, default: 27017
    username: 'admin', // optional
    password: 'secret', // optional
    collection: 'mySessions' // optional, default: sessions
  ,
  secret: '076ee61d63aa10a125ea872411e433b9'
;

然后我可以这样配置它:

app.configure(function()
  // ...
  app.use(express.cookieParser());
  app.use(express.session(
    secret: conf.secret,
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore(conf.db)
  ));
  // important that this comes after session management
  app.use(app.router);
  // ...
);

最后使用 mongoose 再次连接到 mongodb:

var dbUrl = 'mongodb://';
dbUrl += conf.db.username + ':' + conf.db.password + '@';
dbUrl += conf.db.host + ':' + conf.db.port;
dbUrl += '/' + conf.db.db;
mongo.connect(dbUrl);
mongo.connection.on('open', function () 
  app.listen(3000);
);

【讨论】:

干得好!我唯一让我的麻烦更加复杂的是确保你的“app.use(app.router);”放在“app.use(express.session...”之后。 对于最近试图让它工作的任何人:似乎从 v0.1.9 开始,您需要将 express 设置为变量 (var express = require('express')),然后将其传递给 connect-mongo ( var MongoStore = require('connect-mongo')(express))。这是可行的,因为 express 暴露了 connect 的所有底层部分,而 connect-mongo 实际上是一个将 connect 对象作为参数的函数。 为了避免 EADDRINUSE 错误,我不得不从您拥有的代码底部删除“app.listen(3000)”行,因为我已经在其他地方做我的 .listen 了。该部分只需要完成一次,用于启动实际的快速网络服务器本身——与 mongodb 连接本身无关。只是一个注释! 好的,我已经到了这里,但是现在我如何与会话进行交互?设置和获取值.. @Hadesara 这里有关于 expressjs 和会话的优秀文档:expressjs-book.com/forums/topic/…【参考方案5】:

请包含

app.use(express.cookieParser());

直接在之前

app.use(express.session(

否则会报如下错误,

TypeError:无法读取未定义的属性“connect.sid”

【讨论】:

这可以挽救生命。互联网在这方面是错误的 - 结果顶部没有一个例子甚至暗示了这一点。 非常感谢 - 解决了问题! 感谢您的提示,但下一次,只需编辑我的答案并添加缺失的行,这样其他人就不必阅读另一个答案...【参考方案6】:

对于快递 4x:

var express = require('express'),
    session = require('express-session'),
    MongoStore = require('connect-mongo')(session),
    mongo = require('mongoose');

var conf = 
  db: 
    db: 'myDb',
    host: '192.168.1.111',
    port: 6646,  // optional, default: 27017
    username: 'admin', // optional
    password: 'secret', // optional
    collection: 'mySessions' // optional, default: sessions
  ,
  secret: '076ee61d63aa10a125ea872411e433b9'
;

app.configure(function()
  app.use(express.cookieParser());
  app.use(session(
    secret: conf.secret,
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore(conf.db)
  ));
);

var dbUrl = 'mongodb://';
dbUrl += conf.db.username + ':' + conf.db.password + '@';
dbUrl += conf.db.host + ':' + conf.db.port;
dbUrl += '/' + conf.db.db;
mongo.connect(dbUrl);
mongo.connection.on('open', function () 
  app.listen(3000);
);

session已经被移到了它自己的模块中,所以你需要require它并在配置session时使用session

【讨论】:

在第 3 行中,在 require 语句之后的 (session) 究竟是什么意思。是否像(会话)被传递给 mongoStore【参考方案7】:

我只是偶然发现了mongoose-session

非常轻巧,可以无缝地为我工作。来自github...

安装

npm install mongoose-session

使用

var express = require('express');

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/db');

var app = express();

app.use(require('express-session')(
    key: 'session',
    secret: 'SUPER SECRET SECRET',
    store: require('mongoose-session')(mongoose)
));

【讨论】:

来自 repo mongoose-session不活跃。请改用 connect-mongo。反正这样更好。

以上是关于node.js + express.js:使用 mongodb/mongoose 处理会话的主要内容,如果未能解决你的问题,请参考以下文章

Node.js + Express.js |尝试设置 HTTPS 服务器

是否可以使用 express.js 清除 node.js 需要缓存?

node.js + express.js:使用 mongodb/mongoose 处理会话

使用 Express.js 在 Node.js 中设置路由的最佳方式

在 express.js 中为 node.js 使用 jsonp

使用 express.js 在 node.js 中提供 html 的最佳实践是啥?