Node.js - Session doesn't persist through res.

2019-03-20 09:48发布

问题:

I'm (almost) successfully using Node.js with Express and Redis to handle sessions.

The problem I'm having is that the session is not kept when I use res.redirect().

Here is how I can see it :

req.session.username = username.toString();
console.log(req.session);
res.redirect('/home');

The console.log() prints :

{ lastAccess: 1322579131762,
  cookie:
   { path: '/',
     httpOnly: true,
     _expires: Tue, 29 Nov 2011 15:06:31 GMT,
     originalMaxAge: 60000 },
  username: 'admin' }

Now, here is the following code :

app.get('/home', [app.requireLogin], function(req, res, next) {
// Not showing the rest as it's not even getting there
// Instead, here is what's interesting
app.requireLogin = function(req, res, next) {
  console.log(req.session);

This console.log() prints out this :

{ lastAccess: 1322579131775,
  cookie:
   { path: '/',
     httpOnly: true,
     _expires: Tue, 29 Nov 2011 15:06:31 GMT,
     originalMaxAge: 60000 } }

Clearly, the 'username' object has disappeared. The session has not kept it, and just rebuilt a new one.

How can I solve this? Don't hesitate if you need any information.

Here is the code where I set the session management :

app.configure(function() {
  // Defines the view folder and engine used.
  this.set('views', path.join(__dirname, 'views'));
  this.set('view engine', 'ejs');

  // Allow parsing form data
  this.use(express.bodyParser());

  // Allow parsing cookies from request headers
  this.use(express.cookieParser());
  // Session management
  this.use(express.session({
    // Private crypting key
    secret: 'keyboard cat',
    store: new RedisStore,
    cookie: {
      maxAge: 60000
    }
  }));
  this.use(app.router);
});

Here is the whole project (I mean, parts of it), on gist : https://gist.github.com/c8ed0f2cc858942c4c3b (ignore the properties of the rendered views)

回答1:

Alright, I found the solution. The problem is that the time in maxAge was added to the current date. So, in the browser side, the cookie was set to expire at the GMT time shown.

The problem was the following : I use a virtual machine to test node.js, and, you know... sometimes, you suspend your machine.

Well, what happened is that the machine's time was two days late. So, whenever the cookie was set on the server side, the client side thought the cookie was already expired, since my host machine was not two days late.

Another stupid outcome.



回答2:

Did you try with different browsers ? Are you keeping the same session id between page redirects ?

You could add req.session.cookie.expires = false; before redirecting...



回答3:

Your code looks pretty solid, but is there a reason you're using client.end()? It forcibly closes the redis connection and is not clean. I don't think you need it at all:

https://github.com/mranney/node_redis/issues/74

I am not sure about the underlying architecture for connect-redis, but I'm wondering if calling client.end is what's resetting your sessions. What happens if you take those out?



回答4:

I was having a similar problem in that I was setting something on the session that was not persisting outside the app.get() it was set in.

My problem turned out to be that I was not doing a res.redirect() at the end of my app.get(). Looks like I was setting something on a request object and then allowing it to get garbage collected.

I added a res.redirect( '/nextmethod' ) and the data persists just fine.



回答5:

Surely you need to save that session in some way, this might work.

req.session.regenerate(function(){
    req.session.username = username.toString();
    res.redirect('/home');
});