Node.js&Express会话问题

我遇到了一个会话问题,有时刚刚设置的会话variables在下一个页面请求中是未定义的。 我通常必须再次通过stream程才能正确设置variables。

我可以确认,我没有试图将会话variables设置为undefined; 他们有合法的价值。

在我的应用程序中,用户从/ twitter / connect /移动到/ twitter / callback /。 前者从twitter中获取一些oauth数据,后者将用户logging到twitter中。

/ twitter / connect /很简单:

app.get('/twitter/connect/?', function(req, res){ consumer().getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret, results){ if (error){ // error handling here } else { req.session.oauthRequestToken = oauthToken; req.session.oauthRequestTokenSecret = oauthTokenSecret; // if I console.log the two session variables above // they have the proper values. res.redirect("https://twitter.com/oauth/authorize?oauth_token="+req.session.oauthRequestToken); } }); }); 

之后,twitter将它们发回到/ twitter / callback /:

 app.get('/twitter/callback/?', function(req, res){ console.log(req.session.oauthRequestToken); console.log(req.session.oauthRequestTokenSecret); // more often than not, the two variables above are // undefined. but not always. usually on the first // pass, never on the second. }); 

我不知道发生了什么,我可以确认会话variables设置正确,他们只是不保持页面请求之间的价值,但只是第一次。

这是我如何创build我的服务器:

 app.configure('development', function(){ app.use(express.cookieParser()); app.use(express.session({ secret:'yodawgyo' })); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); app.use(express.logger()); app.use(express.static(__dirname + '/public')); app.set('view engine', 'ejs'); app.set('view options', { open: '{{', close: '}}' }); }); 

我现在只是有一个开发环境。 我已经安装了Node 0.5.0,但也在0.4.1上看到了这个问题。 我使用快车2.3.2。

任何帮助深表感谢。

在Connect的会话中,任何处理程序都可以将req.session.anything设置为任何值,Connect将在处理程序调用end()时存储该值。 如果有多个同时在线的请求,这是危险的; 当他们完成时,一个会话的价值会打破另一个。 这是拥有这样一个简单的会话API (或直接看到会话源 )的结果,它不支持自动获取和设置会话属性。

解决方法是尝试根据需要为会话中间件提供尽可能less的请求。 这里有一些提示:

  1. 将您的express.static处理程序放在会话中间件的上方。
  2. 如果不能移动某些不需要会话的处理程序,那么也可以将会话中间件configuration为忽略不使用req.session的任何path, req.session是说express.session.ignore.push('/individual/path')
  3. 如果任何处理程序不写入会话(也许它只会从会话中读取),请设置req.session = null; 在调用res.end();之前res.end(); 。 那么它不会被重新保存。

如果一次只有一个请求执行读取 – 修改 – 写入会话,那么破坏的可能性就会降低。 我希望将来Connect会有一个更精确的会话中间件,但是API当然会比现在更复杂。

只是同样的问题挣扎,并得到解决。 简单的答案是打电话

  Session.save() 

明确地说,如果你不能在快速回复中回复,在回复结束时给你打电话。

参考

我对github提出了一个反对Express的问题 ,但几分钟之后才发现有什么问题。 不知道你是否有同样的问题,但为了完整性:

在我的情况下,我正在testing转到http:// localhost:8003,但OAuth提供商redirect到http:// 主机名 :8003 。 相同的框/服务器/网页,但不同的域名意味着浏览器发送不同的cookie,因此,expression获得不同的会话ID和会话数据。 只要我开始在http:// hostname :8003testing ,一切正常。

我的代码在结构上与您的代码相似。 在我的情况下,但是,我的POST操作源自JQuery $ .post函数。 但是,我不知道这是否有明显的区别

我最终不得不做的是在我的快速路由例程的POST操作定义的末尾发送一个“垃圾”响应,即

res.send("hoo hee ha ha unimportant junk data");

通过在最后包含这个,我能够触发一个成功的函数(AJAX post尝试的callback函数)。 我在那里插入了redirect,而不是把它放在快车路线上。

使用AJAX Post window.redirect();

不要使用AJAX Post: $res.redirect("someurl");

这是因为浏览器显然不会在AJAX响应上redirect,所以您必须使用Javascript,如下所述: Express js – 不能redirect

希望帮助别人,它为我解决了问题,和平。