req.session在路线中未定义

时间:2014-04-06 23:55:30

标签: node.js express passport.js

我正在使用expressjspassportjs构建一个简单的网站,我遇到了无法访问路由中的会话变量的问题。

这个主题有很多主题,但解决方案对我不起作用。看起来我的错误在其他地方。

我的应用配置如下:

app.configure(function() {
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.logger());
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.session({
        path: '/',
        secret: 'very secret'
    }));

    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

一旦护照验证了Twitter帐户,它就被重定向到这个网站:

app.get('/auth/twitter/callback',
    passport.authenticate('twitter', {
        failureRedirect: '/login'
    }),
    function(req, res) {
        res.redirect('/');
        console.log("populate session")
        populateSession(req, res);
    });

这是有效的,因为我在登录时看到控制台中的“填充会话”输出。

populateSession()看起来像这样:

function populateSession(req, res) {
    User.findOne({
        twitterID: req.user.id
    }, function(err, result) {
        if (result) {
            // Store data to session
            req.session.twitterAccessToken = result.twitterAccessToken;
            req.session.twitterAccessTokenSecret = result.twitterAccessTokenSecret;
            req.session.lastfmAccountName = result.lastfmAccountName;

            console.log("in session: " + req.session.lastfmAccountName)
        }
    })
}

“会话中”以正确的方式打印。因此会话本身有效。现在我的问题是我想要访问路由中的会话变量,因为我想将它们传递给我的视图模板,如下所示:

app.get('/account', ensureAuthenticated, function(req, res) {
    console.log(req.session)
    console.log("lastfm nick " + req.session.lastfmAccountName)
    res.render('account', {
        user: req.user,
        lastfmnick: req.session.lastfmAccountName
    });

这就是我遇到问题的地方。 req.session包含护照填充的所有推特字段,但req.session.lastfmAccountNameundefined

知道那里有什么问题或是否有更好的方法将变量传递给视图?我觉得如果它可以存储在会话中,那么对所有路由中的字段进行数据库查询并不是一个好主意。

谢谢!

2 个答案:

答案 0 :(得分:3)

会话将automatically be saved when the response ends,在本例中为res.redirect(),这是在对会话进行修改之前完成的。

function(req, res) {
    res.redirect('/');         // ends the response, saving the session

    populateSession(req, res); // modifies the session without saving
});

由于.findOne()是异步的,如果您修改populateSession()以在查找完成时接听并调用回调,则可以控制顺序以便首先修改会话:

function populateSession(req, res, next) {
    User.findOne({
        twitterID: req.user.id
    }, function(err, result) {
        if (result) {
            // ...
        }

        if (next) next(err);
    })
}
app.get('/auth/twitter/callback',
    /* ... */,
    function(req, res) {
        populateSession(req, res, function () {
            res.redirect('/');
        });
    });

它还允许您使用populateSession作为中间件:

app.get('/auth/twitter/callback',
    /* ... */,
    populateSession,
    function(req, res) {
        res.redirect('/');
    });

答案 1 :(得分:0)

 app.use(lib.express.cookieParser(lib.config.cookieSecret));
 app.use(lib.express.session({
secret: 'very secret'
 })
 }));

这两行应该按顺序连续。