会话未定义 - 使用Connect-Redis / ExpressJS / Node

时间:2013-07-11 17:59:29

标签: javascript node.js express redis connect

今天早上醒来发现Nodejitsu发出以下错误:

Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and will not scale past a single process.

'那么好吧!'我心想 - 然后我去寻找更合适的东西。我决定使用Redis,并立即开始在我的应用程序中实现connect-redisnode-redis

但是,在多次尝试修复后,以下错误仍然存​​在。错误如下:

TypeError: Cannot set property 'loggedIn' of undefined
        at /Users/Ryan/Aggregus/server.js:300:25
        at Promise.<anonymous> (/Users/Ryan/Aggregus/object_models/user.js:60:5)
        at Promise.<anonymous> (/Users/Ryan/Aggregus/node_modules/mongoose/node_modules/mpromise/lib/promise.js:162:8)
        at Promise.EventEmitter.emit (events.js:95:17)
        at Promise.emit (/Users/Ryan/Aggregus/node_modules/mongoose/node_modules/mpromise/lib/promise.js:79:38)
        at Promise.fulfill (/Users/Ryan/Aggregus/node_modules/mongoose/node_modules/mpromise/lib/promise.js:92:20)
        at /Users/Ryan/Aggregus/node_modules/mongoose/lib/query.js:1813:13
        at model.Document.init (/Users/Ryan/Aggregus/node_modules/mongoose/lib/document.js:243:11)
        at completeOne (/Users/Ryan/Aggregus/node_modules/mongoose/lib/query.js:1811:10)
        at /Users/Ryan/Aggregus/node_modules/mongoose/lib/query.js:1779:11

loggedIn只是指req.session.loggedIn,我用来跟踪登录用户的会话变量。以下是相关的应用程序代码:

var express = require('express');
var crypto = require('crypto');
var mongoose = require('mongoose');
var nodemailer = require('nodemailer');
var request = require('request');
var underscore = require('underscore');
var mandrill = require('node-mandrill')('0bFNPDenlDiZtu7aXujDQQ');
var connect = require('connect');
var engines = require('consolidate');
var fs = require('fs');
var redis = require("redis").createClient();

var RedisStore = require('connect-redis')(express);

var sessionStore = new RedisStore({
    client: redis
});

var stripe_api_key = 'KEY';
var Stripe = require('stripe')(stripe_api_key);

var app = express(); 

app.configure(function() {
    app.engine('html', engines.jade);
    app.set('view engine', 'html');
    app.use(express.cookieParser()); 
    app.use(express.bodyParser());
    app.use(express.session({secret: "svtabyrki4q786as37c785ta8vi56aiw4i8w467acv", store: sessionStore}));
    app.use(express.static(__dirname + '/www'));
    app.use(express.compress()); 
    app.use(app.router);

});

// Mongoose Connection

var db = mongoose.connection;

var dbURI = 'HIDDENURL';

db.on('disconnected', function() {
    mongoose.connect(dbURI, {server:{auto_reconnect:true}});
});

db.on('error', function(error) {
  console.error('Error in MongoDb connection: ' + error);
  mongoose.disconnect();
});

mongoose.connect(dbURI, {server:{auto_reconnect:true}});

// Mongoose Object Models

var User = require('./object_models/user')(mongoose, nodemailer, mandrill);
var Notifications = require('./object_models/notification')(mongoose, nodemailer);
var Experience = require('./object_models/experience')(mongoose, nodemailer);
var Booking = require('./object_models/booking')(mongoose, nodemailer);
var Review = require('./object_models/review')(mongoose, nodemailer);
var Heart = require('./object_models/heart')(mongoose, nodemailer);
var Message = require('./object_models/message')(mongoose, nodemailer);

// Nodemailer Settings

var smtpTransport = nodemailer.createTransport("SMTP",{
    service: "Gmail",
    auth: {
        user: "ryan@aggregus.com",
        pass: pwd
    }
});

// Bootstrap Call

app.get('/', function(req, res) {
    res.render('../index.html');
    console.log("WUSUP");
});

为了进一步明确,以下是我在此之前尝试的内容无效:

  1. 我已在app.use(express.cookieParser());来电之前放置了express.session,因为此主题的大多数文章均有提及。
  2. 我确保我的new RedisStore调用在初始化时直接引用client
  3. 我在app.use(app.router)和'express.cookieParser'的初始调用之后放置了express.session
  4. 我的Redis服务器通过createClient()电话完全正常运行。
  5. similar question是通过防止在Express'sessionStore初始化之前调用app.use而无法进行app.router初始化来解决的。

    因此,TL; DR:在使用connect-redis时,我的会话变量返回undefined。我已经在网上搜索了答案,我唯一的线索是在Express自己的会话处理之前app.router正在启动。那个小故障发生在我身边的地方。 Stack Overflow的众神怜悯我可怜的灵魂。

    编辑:认为package.json可能很方便参考。通过NodeJitsu生成:

    {
      "name": "Aggregus",
      "subdomain": "aggregus-Aggregus",
      "scripts": {
        "start": "node server.js"
      },
      "version": "0.0.0-14",
      "engines": {
        "node": "0.8.x"
      },
      "dependencies": {
        "connect": "2.7.8",
        "consolidate": "0.9.1",
        "express": "3.2.2",
        "jade": "0.30.0",
        "mongoose": "3.6.9",
        "node-mandrill":"1.0.1",
        "nodemailer": "0.4.1",
        "request":"2.22.0",
        "stripe": "1.3.0",
        "underscore":"1.4.4"
      }
    }
    

1 个答案:

答案 0 :(得分:6)

您正在调用connect-redis错误,并且您不需要单独安装redis。但是,我在package.json中没有看到connect-redis,所以你应该npm install --save connect-redis。然后做这样的事情:

var express = require('express');
var RedisStore = require('connect-redis')(express);
var ports = require('./classes/ports.js');
var config = require('./config/config.js');
var routes = require('./routes');
var errors = require('./classes/errors.js');

var app = express();
ports(app);
app
.use(express.logger())
.use(express.compress())
.use(express.cookieParser())
.use(express.session({
  store: new RedisStore({
    port: config.redisPort,
    host: config.redisHost,
    db: config.redisDatabase,
    pass: config.redisPassword
  }),
  secret: 'Your secret here',
  proxy: true,
  cookie: { secure: true }
}))
.use(express.favicon(__dirname + '/../public/img/favicon.ico'))
.use(express.bodyParser())
.use(express.methodOverride())

routes(app);
errors(app);