2011-12-01 97 views
7

我(几乎)成功地使用Node.js与Express和Redis来处理会话。Node.js - 会话不会持续通过res.redirect()

我遇到的问题是当我使用res.redirect()时,会话不被保留。

这是我如何能看到它:

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

的执行console.log()打印:

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

现在,这里是下面的代码:

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

这console.log()打印出此:

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

显然,'username'对象已经消失。会议没有保留它,只是重建了一个新的会议。

我该如何解决这个问题?如果您需要任何信息,请不要犹豫。

这里是我设置会话管理代码:

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

这里是整个项目(我的意思是,部分吧),对要点:https://gist.github.com/c8ed0f2cc858942c4c3b(忽略的渲染视图属性)

+0

您还可以粘贴包含Redis会话存储的代码吗?这里有一个超时选项,可能你意外地把它设置得太低了。 – alessioalex

+0

增加:)它设置在60秒,我显然不使用60秒来写入凭据... –

+0

我认为这是一个小项目,我认为最好将它发布到某处(gist,pastie)并给一条链接。我敢打赌,这个错误在某种程度上是不粘贴的。 (只是猜测) – alessioalex

回答

6

好吧,我找到了解决办法。问题是maxAge中的时间已添加到当前日期。所以,在浏览器端,cookie被设置为在显示的GMT时间过期。

问题如下:我使用虚拟机来测试node.js,并且,您知道......有时候会暂停您的计算机。

那么,发生了什么事是机器的时间晚了两天。因此,无论何时在服务器端设置cookie,客户端都认为cookie已经过期,因为我的主机迟了两天。

另一个愚蠢的结果。

1

你的代码看起来很稳固,但是你有使用client.end()的原因吗?它强制关闭redis连接并且不干净。我不认为你需要它在所有:

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

我不知道有关连接,Redis的底层架构,但我想知道,如果在调用client.end是什么重置您的会话。如果你把它们拿出来会发生什么?

+0

谢谢,我不知道。我认为它会更干净。虽然它并没有解决问题,但我已经+1了你:) –

0

当然,你需要以某种方式保存会话,这可能会起作用。

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

这不会改变任何东西,不幸的是。顺便说一下,这个再生功能有什么意义呢? –

+0

如果您要修改存储在持久数据库中的数据,那么在您可以在系统的其他部分使用它之前,您需要*保存*它是合乎逻辑的。令我惊讶的是,req.session.username变量在不保存任何东西的情况下仍然存在*也许它是作为一项功能自动完成的 –

2

你试过不同的浏览器吗?你是否在页面重定向之间保持相同的会话ID?

你可以重定向前添加req.session.cookie.expires = false; ...

1

我有一个类似的问题在我设置上并没有将它保持在设定的app.get()外会话东西。

我的问题竟然是,我是res.redirect()在我的app.get()的末尾。看起来我正在对请求对象设置一些东西,然后让它进行垃圾收集。

我加了一个res.redirect('/nextmethod'),数据一直很好。