2011-05-04 50 views
10

我遇到会话问题,其中会话变量I 只是集合 未定义在下一个页面请求上。我通常必须再次通过流程 才能正确设置变量。Node.js&Express会话问题

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

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

/叽叽喳喳/连接/很简单:

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

之后,微博送他们回/叽叽喳喳/回调/:

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

我不知道发生了什么事情,我可以确认会话变量设置正确,它们只是不会在页面请求之间保持它们的值,而只是第一次。

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

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。

任何帮助,非常感谢。

+2

我有调用API的完全相同的问题。我很确定会话信息在重定向时正在丢失。也就是说,如果我在浏览器中刷新页面,我可以看到我在会话中放置的内容仍然存在。但是,如果我通过某个外部站点(例如oauth提供程序)的重定向到达*相同页面*,则该会话是完全空白的。不知道问题是什么。 – 2011-06-08 20:57:52

+0

更新:看起来像您为重定向的请求获得了不同的会话ID。 – 2011-06-08 21:34:53

回答

17

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

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

  1. 将您的express.static处理程序放在会话中间件的上方。
  2. 如果无法移动某些不需要会话的处理程序,还可以配置会话中间件以忽略任何不使用req.session的路径,如express.session.ignore.push('/individual/path')
  3. 如果任何处理程序未写入会话(可能只会从会话中读取),请在致电res.end();之前设置。然后它不会被重新保存。

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

+1

感谢您的详细回复。不幸的是,这并没有解决我的问题。我将静态处理程序移到了会话中间件的上面,但几乎可以完成所有工作。所有路由(仅其中4个)直接使用会话,或者通过使用会话的中间件。任何其他想法? – ehynds 2011-05-06 15:21:45

+0

感谢您的好解释。我已经开通了一个连接问题来跟踪它:https://github.com/senchalabs/connect/issues/854 – Matt 2013-08-01 07:15:16

+0

omg。你的解决方案修复了它。出于某种原因,我的会话在POST页面之间死亡。我不知道为什么。但它只是。一旦我将会话中间件上面的静态代码移动了! – 2014-05-26 14:54:52

4

我提交了issue against Express about github,但几分钟后发现有什么问题。不知道你是否有同样的问题,但为了完整性:

在我的情况下,我测试了去http://localhost:8003但OAuth提供商重定向到http://hostname:8003。相同的盒子/服务器/网页,但不同的域名意味着浏览器发送不同的cookies,因此,express会获得不同的会话ID和会话数据。只要我开始在http://hostname:8003进行测试,一切正常。

0

我的代码与您的结构类似。但是,在我的情况下,我的POST操作源自JQuery $ .post函数。我不知道如果让一个明显的区别,但是

我最终什么事不得不做的就是发送在我的快递路由常规POST操作定义的结尾是“垃圾”反应,即

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

通过在最后包含这一点,我能够触发成功功能(AJAX发布尝试的回调)。我在那里插入了重定向,而不是将它放置在快速路线中。

与使用AJAX后window.redirect();

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

这是因为浏览器显然不会对AJAX响应重定向,所以你必须使用JavaScript,如下所述:Express js - can't redirect

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

+0

我爱一点点老'_hoo嘿哈哈_。没有什么比较喜欢它。 – 2014-03-03 14:44:38

5

只是与同样的问题挣扎,并得到解决。 简单的答案是调用

Session.save() 

明确,如果你不能在快递会话回复的响应结束调用它。

Reference