会话变量不存储在node.js中

use*_*679 1 session node.js express

我搜索并发现很多类似的问题,会话变量设置为undefined,但我找到的答案似乎都没有适用.

我的路由器文件中有这个功能:

exports.loginHandler = function(req, res){
    username = req.body.username;
    password = req.body.password;
    readAccount(username, function(acct){
        if (acct.password = password){
            req.session.username = username;
            console.log(username+' logged in'+' pass: '+acct.password);
        };
    });
    res.redirect('/');
};
Run Code Online (Sandbox Code Playgroud)

console.log执行得很好,username和acct.password都有适当的值.但是,req.session.username最终被设置为undefined.

这是readAccount函数:

readAccount = function(user, callback){
    AM.login(user, function(acct){
        callback(acct);
    });
};
Run Code Online (Sandbox Code Playgroud)

这是AM.login:

exports.login = function(user, callback){
    accounts.findOne({username: user}, function(err, result){
    if (err) throw err;
    callback(result);
    })
}
Run Code Online (Sandbox Code Playgroud)

我猜测会话变量不能在条件下设置,因为这种类型的错误似乎并不常见.

Jon*_*ski 5

问题是您在设置session.username属性之前重定向,结束响应并保存会话.这是因为readAccount,通过它accounts.findOne是异步的,并且在res.redirect()调用之前不会完成.

您可以通过移动确保其执行顺序res.redirect()进入readAccount回调:

exports.loginHandler = function(req, res){
    username = req.body.username;
    password = req.body.password;

    readAccount(username, function(acct){
        if (acct.password = password){
            req.session.username = username;
            console.log(username+' logged in'+' pass: '+acct.password);
        };

        res.redirect('/');
    });
};
Run Code Online (Sandbox Code Playgroud)

另外,请注意throw异步操作中的错误.回调将具有与启动函数(例如readAccount)不同的调用堆栈,这使得catch错误变得困难.这就是为什么许多Node for Node将错误作为参数传递的原因.