2014-10-23 2 views
13

Sto costruendo un sito Web utilizzando Node.js, Express e Redis per la gestione delle sessioni. Per qualsiasi motivo, se ho una variabile di sessione (isLoggedIn in questo esempio) e aggiorno la pagina, la variabile non viene salvata, tuttavia, se chiamo req.session.save() dopo aver impostato la variabile, viene salvata su Redis (redis -cli monitor mostra questo - non chiamare save() indica che la variabile non è presente, mentre chiamare lo save() lo mostra).Sessioni non salveranno in Node.js senza req.session.save()

Sto usando questo per impostare e avviare il server:

var express = require('express'); 
var path = require('path'); 
var favicon = require('serve-favicon'); 
var logger = require('morgan'); 
var cookieParser = require('cookie-parser'); 
var bodyParser = require('body-parser'); 
var swig = require('swig'); 
var session = require('express-session') 
var RedisStore = require('connect-redis')(session); 

var routes = require('./routes/index'); 
var users = require('./routes/users'); 

var app = express(); 

// Configure the favicon first. This avoids other middleware from processing the request if we know the request is for the favicon. 
app.use(favicon(__dirname + '/public/images/favicon.ico')); 

// All other requests will require everything else. 

// Set up the view engine. 
app.set('view engine', 'html'); 
app.set('views', path.join(__dirname, '/views')); 
app.engine('html', swig.renderFile); 

// Set up our logger. 
app.use(logger('dev')); 

// Set up JSON parsing. 
app.use(bodyParser.json()); 

// Set up encoded URL parsing. 
app.use(bodyParser.urlencoded()); 

// Set up the cookie parser. 
app.use(cookieParser('thedogsleepsatnight')); 

// Set up our session store. This will use Redis as our session management. 
app.use(session({ 
    resave: true, 
    saveUninitialized: true, 
    secret: "thedogsleepsatnight", 
    store: new RedisStore() 
})); 

app.use(require('stylus').middleware(path.join(__dirname, 'public'))); 
app.use(express.static(path.join(__dirname, 'public'))); 

app.use('/', routes); 

E poi, in questa strada, ho:

var express = require('express'); 
var router = express.Router(); 

router.get('/', function(req, res) { 
    console.log(req.session.isLoggedIn); 
    if (req.session.isLoggedIn) { 
     console.log("Logged in!"); 
    } else { 
     console.log("Not logged in"); 
    } 

    res.render('index'); 
}); 

router.post('/login', function(req, res) { 
    console.log("Going to set isLoggedIn. Currently: " + req.session.isLoggedIn); 
    req.session.isLoggedIn = true; 
    console.log("Set isLoggedIn. Currently: " + req.session.isLoggedIn); 
}); 

module.exports = router; 

Da questo, dovrei essere in grado di navigare a /login, impostare la sessione isLoggedIn su true e salvare automaticamente su Redis. Dopo di che, di dirigersi verso / dovrebbe dirmi che ho effettuato l'accesso. Loading /login non impostare la variabile, il secondo registro mostra che, ma carico / dice che non sto collegato. Redis-cli monitor mostra

1414076171.241836 "setex" "sess:FIDJ9qDbX_0u9pzlC6VZEW76zZcyiPME" "86400" "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"}}" 

al momento del salvataggio, che non include la variabile isLoggedIn, ma aggiungendo in req.session.save() spettacoli:

1414076475.601644 "setex" "sess:FIDJ9qDbX_0u9pzlC6VZEW76zZcyiPME" "86400" "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"isLoggedIn\":true}" 

Qualche idea su questo che devo chiamare req.session.save() quando tutti gli esempi che ho visto non usare vero?

+0

puoi indicare uno di detti esempi? mi sarei aspettato di dover usare .save() per spingere le modifiche all'archiviazione. –

+0

Certo, http://tipstak.blogspot.com/2014/01/session-management-example-using-redis-on-express.html. Imposta userId senza chiamare save. In un'altra domanda SO, http://stackoverflow.com/questions/14014446/how-to-save-and-retrieve-session-from-redis, è spiegato che tutto dovrebbe essere fatto automaticamente, dove save() è lì semplicemente per il salvataggio manuale. – PuppyKevin

+0

C'è qualcosa nel middleware che si sta utilizzando che potrebbe impedire o interrompere il modo in cui i proxy Express-Session il metodo finale? https://github.com/expressjs/session/blob/master/index.js#L194 'res.render' esegue quel metodo? –

risposta

59

Ok, l'ho capito. Metterò qui la risposta per chiunque altro si imbatta in questo.

Per le richieste GET, il server presuppone che si stiano inviando i dati e salverà automaticamente i dati della sessione una volta che il percorso è stato completamente elaborato.

Per le richieste POST (che cosa sto usando), tuttavia, non viene fatta la stessa ipotesi. Gli stati di sessione vengono salvati solo in una delle due condizioni: o quando i dati vengono inviati (tramite res.send, res.redirect, ecc.) O se si chiama manualmente req.session.save(). Stavo già chiamando/login da una richiesta AJAX, semplicemente non restituivo nulla se certe condizioni erano soddisfatte. Avendo il server rispondere al client con alcuni dati dopo aver impostato la variabile di sessione risolto questo.

+0

Grazie mille per la risposta, ho lottato per un po ':) – Bardelman

+0

Grazie uomo, io sono quasi impazzendo perché la mia sessione non è cambiata durante la richiesta. risparmi la mia giornata! –

+0

Salvato il mio giorno. Ero quasi arrabbiato –