我正在使用expressjs和passportjs构建一个简单的网站,我遇到了无法访问路由中的会话变量的问题。
这个主题有很多主题,但解决方案对我不起作用。看起来我的错误在其他地方。
我的应用配置如下:
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.lastfmAccountName
为undefined
。
知道那里有什么问题或是否有更好的方法将变量传递给视图?我觉得如果它可以存储在会话中,那么对所有路由中的字段进行数据库查询并不是一个好主意。
谢谢!
答案 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'
})
}));
这两行应该按顺序连续。