2014-10-23 10 views
13

Buduję witrynę przy użyciu Node.js, Express i Redis do zarządzania sesjami. Z jakiegoś powodu, jeśli mam zmienną sesji (isLoggedIn w tym przykładzie), a ja odświeżam stronę, zmienna nie zostanie zapisana, jednak po wywołaniu req.session.save() po ustawieniu zmiennej, zostanie ona zapisana do Redis (redis -cli monitor pokazuje to - nie wywołanie save() pokazuje, że zmiennej nie ma, podczas gdy wywołanie save() pokazuje ją).Sesje nie będą zapisywane w pliku Node.js bez req.session.save()

używam tego, aby skonfigurować i uruchomić serwer:

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

A potem, w tej trasie, mam:

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; 

Od, że powinienem być w stanie poruszać do /login, ustaw sesję isLoggedIn na wartość true, która powinna automatycznie zapisać do Redis. Po tym, kierując się / powinien mi powiedzieć, że jestem zalogowany. Ładowanie /login ma ustawić zmienną, drugi log pokazuje, że ładowanie / ale mówi, że nie jestem zalogowany. Redis-cli Monitor pokazuje

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

na oszczędność, która nie obejmuje zmienną isLoggedIn, ale dodając req.session.save() Wystawy:

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

Każdy pomysł, dlaczego muszę zadzwonić req.session.save() gdy wszystkie przykłady widziałem nie używać to?

+0

możesz wskazać jeden z wymienionych przykładów? spodziewałbym się, że będę musiał użyć funkcji .save(), aby przesłać zmiany do pamięci masowej. –

+0

Oczywiście, http://tipstak.blogspot.com/2014/01/session-management-example-using-redis-on-express.html. Ustawia ID użytkownika bez wywoływania zapisu. W innym pytaniu SO, http://stackoverflow.com/questions/14014446/how-to-save-and-retrieve-session-from-redis, wyjaśniono, że powinno to być zrobione automatycznie, gdzie save() jest po prostu do ręcznego zapisywania. – PuppyKevin

+0

Czy jest coś w używanym oprogramowaniu pośredniczącym, które może zapobiec lub złamać sposób sesji pośredniej w czasie sesji ekspresowej? https://github.com/expressjs/session/blob/master/index.js#L194 czy 'res.render' wykonuje tę metodę? –

Odpowiedz

59

OK, więc, wymyśliłem to. Postawię odpowiedź tutaj dla każdego, kto zostanie przyłapany na tym.

W przypadku żądań GET serwer zakłada, że ​​zamierzasz odesłać dane, i automatycznie zapisze dane sesji po całkowitym przetworzeniu trasy.

Dla żądań POST (co używam), jednak to samo założenie nie jest wykonane. Stany sesji są zapisywane tylko w jednym z dwóch warunków - podczas wysyłania danych (przez res.send, res.redirect itd.) Lub ręcznego wywoływania req.session.save(). Już dzwoniłem/logowałem się z żądania AJAX, po prostu nie zwracałem niczego, jeśli spełnione zostały pewne warunki. Posiadanie serwera, aby odpowiedział klientowi z pewnymi danymi po ustawieniu zmiennej sesji, naprawiło to.

+0

Wielkie dzięki za odpowiedź, przez jakiś czas borykałem się z problemami :) – Bardelman

+0

Dzięki, człowieku, jestem prawie oszalałam, ponieważ moja sesja nie zmieniła się podczas prośby. oszczędzasz mój dzień! –

+0

Uratowałem mój dzień. Byłem prawie szalony –

Powiązane problemy