I'm building a website using Node.js, Express, and Redis for session management. For whatever reason, if I have a session variable (isLoggedIn
in this example), and I refresh the page, the variable doesn't get saved, however, if I call req.session.save()
after setting the variable, it does get saved to Redis (redis-cli monitor shows this - not calling save()
shows that the variable isn't there, whereas calling save()
shows it).
I'm using this to set up and start the 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);
And then, in that route, I have:
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;
From that, I should be able to navigate to /login
, have the session set isLoggedIn to true, and that should save automatically to Redis. After that, heading to /
should tell me that I'm logged in. Loading /login
does set the variable, the second log shows that, but loading /
says that I'm not logged in. redis-cli monitor shows
1414076171.241836 "setex" "sess:FIDJ9qDbX_0u9pzlC6VZEW76zZcyiPME" "86400" "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"}}"
upon saving, which doesn't include the isLoggedIn
variable, but adding in req.session.save()
shows:
1414076475.601644 "setex" "sess:FIDJ9qDbX_0u9pzlC6VZEW76zZcyiPME" "86400" "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"isLoggedIn\":true}"
Any idea on why I have to call req.session.save()
when all of the examples I've seen don't use it?
Session management can be done in node. js by using the express-session module. It helps in saving the data in the key-value form. In this module, the session data is not saved in the cookie itself, just the session ID.
This cookie will contain the session's unique id stored on the server, which will now be stored on the client. This cookie will be sent on every request to the server. We use this session ID and look up the session saved in the database or the session store to maintain a one-to-one match between a session and a cookie.
req. session. To store or access session data, simply use the request property req. session , which is (generally) serialized as JSON by the store, so nested objects are typically fine.
Okay, so, I've figured it out. I'll put the answer here for anyone else that happens to get caught on this.
For GET requests, the server assumes that you're going to be sending data back, and will automatically save session data once the route is fully processed.
For POST requests (what I'm using), however, the same assumption isn't made. Session states are only saved in one of two conditions - either when data is being sent out (through res.send
, res.redirect
, etc.), or if you manually call req.session.save()
. I was already calling /login from an AJAX request, I just wasn't returning anything if certain conditions were met. Having the server respond to the client with some data after setting the session variable fixed this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With