2013-07-11 14 views
5

Questa mattina mi sono svegliato per trovare Nodejitsu girare il seguente erroresessione indefinito Utilizzando Connect-Redis/ExpressJS/Node

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

Ho pensato a me stesso - e via sono andato a trovare qualcosa di più adatto. Ho optato per Redis e ho immediatamente iniziato a implementare connect-redis e node-redis nella mia applicazione.

Tuttavia, il seguente errore continua a emergere dopo ripetuti tentativi di correzione. L'errore è la seguente:

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 è semplicemente riferendosi a req.session.loggedIn, una variabile di sessione che uso per tracciare gli utenti registrati. Il seguente è il codice applicazione in questione:

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"); 
}); 

Per fornire ulteriore chiarezza, ecco che cosa ho provato fino a questo punto inutilmente:

  1. ho posto app.use(express.cookieParser()); prima della chiamata express.session , come suggerito dalla maggior parte degli articoli di questo argomento.
  2. Mi sono assicurato che la mia chiamata new RedisStore faccia riferimento allo direttamente dopo l'inizializzazione.
  3. Ho inserito app.use(app.router) dopo entrambe le chiamate di init sia per express.session che per 'express.cookieParser'.
  4. Il server My Redis è completamente funzionante, tramite la chiamata createClient().

Questo similar question è stato risolto da prevenire una piuttosto insignificante app.use inizializzazione di chiamare app.router prima di esprimere sessionStore in fase di inizializzazione.

Pertanto, TL; DR: utilizzando connect-redis, le variabili di sessione restituiscono undefined. Ho setacciato il web alla ricerca di risposte e il mio unico indizio sarebbe che app.router sia stato avviato prima della gestione della sessione di Express. Dove quel piccolo problema si verifica è al di là di me. Gods of Stack Overflow abbi pietà della mia povera anima.

Modifica: Pensato a package.json potrebbe essere utile come riferimento. Generato tramite 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" 
    } 
} 

risposta

5

si sta chiamando collegare-Redis sbagliato, e non è necessario Redis installati separatamente. Tuttavia, non vedo i redis di connessione nel pacchetto package.json, quindi devi npm install --save connect-redis. Poi fare qualcosa di simile:

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

Hey @dankohn Come faccio a impostare una funzione per impostare immediatamente req.user dal cookie prima di passare eventuali richieste? – morgs32

+0

Quasi sicuramente vorrai usare il passaporto o ogni altro. Ecco un esempio di impostazione di un cookie, che potresti eseguire nella parte superiore: http://stackoverflow.com/questions/20484649/csrf-token-not-working-when-submitting-form-in-express/20485620#20485620 – dankohn