2013-07-11 61 views
5

今天早上,我醒來時,發現Nodejitsu紡出以下錯誤會議未定義使用連接-的Redis/ExpressJS /節點

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: "[email protected]", 
     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. 在兩個express.session和'express.cookieParser'的初始調用之後,我已經放置了app.use(app.router)
  4. 通過調用createClient(),我的Redis服務器功能完整。

similar question被防止微乎其微app.use初始化解決調用app.router之前快速sessionStore被初始化。

因此,TL; DR:在使用connect-redis時,我的會話變量返回undefined。我搜索了網上的答案,我唯一的線索是app.router在Express自己的會話處理之前正在啓動。那個小毛病發生在我身上。堆棧溢出的神憐憫我可憐的靈魂。

編輯:認爲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" 
    } 
} 

回答

5

你調用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); 
+0

嘿@dankohn我怎麼設置一個函數來傳遞任何請求緊接在之前設置req.user從cookie? – morgs32

+0

你幾乎肯定想要使用護照或everyauth。以下是設置Cookie的示例,您可以在頂端附近執行此操作:http://stackoverflow.com/questions/20484649/csrf-token-not-working-when-submitting-form-in-express/20485620#20485620 – dankohn