Node.js和Express会话问题

ehy*_*nds 13 javascript node.js

我遇到了会话问题,有时我设置的会话变量在下一页请求时未定义.我通常必须再次检查流程才能正确设置变量.

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

在我的应用程序中,用户从/ twitter/connect /移动到/ twitter/callback /.前者从twitter中检索了一些oauth数据,后者将用户记录到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);      
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

之后,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.
});
Run Code Online (Sandbox Code Playgroud)

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

这就是我创建服务器的方式:

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: '}}'
    });
});
Run Code Online (Sandbox Code Playgroud)

我现在只有一个开发环境.我安装了Node 0.5.0-pre,但在0.4.1上也看到了这个问题.我正在使用快递2.3.2.

任何帮助深表感谢.

yon*_*ran 19

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

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

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

如果一次只有一个请求对会话进行读取 - 修改 - 写入,那么就不太可能进行破坏.我希望将来Connect会有一个更精确的会话中间件,但当然API会比我们现在的更复杂.


小智 5

刚刚遇到同样的问题并解决了问题.简单的答案是打电话

 Session.save() 
Run Code Online (Sandbox Code Playgroud)

明确地,如果您无法在快速会话上回复,请在回复结束时为您调用它.

参考