2013-07-11 7 views
5

Dziś rano obudziłem się znaleźć Nodejitsu kręci się następujący błądSesja Undefined Korzystanie Przyłączenie 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.

Pomyślałem sobie - a potem poszedłem znaleźć coś bardziej odpowiedniego. Zamieszkałem na Redis i od razu zacząłem implementować connect-redis i node-redis do mojej aplikacji.

Jednak następujący błąd nadal występuje po wielokrotnych próbach naprawy. Błąd jest następujący:

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 jest po prostu odnosi się do req.session.loggedIn, zmiennej sesji używam do śledzenia zalogowanych. Poniżej znajduje się kod aplikacji w pytaniu:

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

celu zapewnienia większej jasności, tutaj jest to, co starałem się do tego momentu bezskutecznie:

  1. umieściłem app.use(express.cookieParser()); przed wywołaniem express.session , jak sugerowało większość artykułów z tego tematu.
  2. Zapewniam, że moje wywołanie new RedisStore odwołuje się do client bezpośrednio po inicjalizacji.
  3. Umieściłem app.use(app.router) po obu wywołaniach init dla obu express.session i "express.cookieParser".
  4. Serwer My Redis jest w pełni funkcjonalny, poprzez wywołanie createClient().

Ten similar question został rozwiązany poprzez zapobieganie raczej nieznaczny app.use inicjalizacji zadzwonić app.router przed ekspresowe SessionStore inicjowany.

Tak więc, TL; DR: Przy użyciu connect-redis, moje zmienne sesji zwracają undefined. Przeszukałem sieć w poszukiwaniu odpowiedzi, a moją jedyną wskazówką jest to, że app.router jest uruchamiany przed rozpoczęciem obsługi sesji Express. Gdzie ten mały błąd pojawia się poza mną. Gods of Stack Overflow zmiłujcie się nad moją biedną duszą.

Edytuj: Pomyśl, pakiet.json może być przydatny jako odniesienie. Wygenerowano za pośrednictwem 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" 
    } 
} 

Odpowiedz

5

Dzwonisz pod numer connect-redis i nie potrzebujesz redis zainstalowanych osobno. Jednak nie widzę połączenia-redis w twoim package.json, więc powinieneś npm install --save connect-redis. Następnie wykonaj coś takiego:

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

Hej @dankohn Jak ustawić funkcję, aby natychmiast ustawić ponownie plik z pliku cookie przed przekazaniem jakichkolwiek żądań? – morgs32

+0

Prawie na pewno chcesz korzystać z paszportu lub everyauth. Oto przykład ustawienia pliku cookie, który możesz zrobić w pobliżu: http://stackoverflow.com/questions/20484649/csrf-token-not-working-when-submitting-form-in-express/20485620#20485620 – dankohn