在底部更新!
我的node.js服务器使用express.js来管理会话。登录后,我将一些用户信息存储在req.session中。我有一个注销端点,它只是在发送响应之前从req.session中删除用户数据。
对于用户发出的每个请求,我使用身份验证中间件来确保会话中仍有用户数据,因此删除会话对象中的用户数据将导致任何后续身份验证失败。
要测试我的服务器,我有一个登录的nodeunit测试,调用几个端点,注销,然后尝试调用另一个端点。 我希望最后一个端点在身份验证中失败,因为我先前已经删除了用户数据。相反,当我拨打最后一个电话时,我的用户数据仍然存在。这就好像删除它的注销调用没有写回会话存储区。
这是我的app.js:
app.use(express.cookieParser('secretPassword'));
app.use(express.cookieSession({key: 'someKey'}));
...
app.get('/logout', accounts.logout);
app.get('/account', auth.authenticateSession, accounts.show);
auth.js:
exports.authenticateSession = function(req, res, next) {
if (!req.session.user) {
return res.json(401, {
error: 'Access denied. You must be logged in to make this request.'
});
}
...
}
accounts.js:注销:
exports.logout = function(req, res) {
req.session.user = null;
res.send('Logged out');
};
单元测试:
step1_logIn : function(test) {
var postData = qs.stringify({
accountname: 'testAcct',
accountpassword: 'hello'
});
ct.postAndCall('/login', null, postData, function(resData, res) {
myCookie = res.headers['set-cookie'];
test.ok(res.statusCode === 200);
test.done();
});
},
step2_logout : function(test) {
ct.getAndCall('/logout', myCookie, function(data, res) {
test.ok(data === 'Logged out.');
test.ok(res.statusCode === 200);
test.done();
});
},
step3_ensureLoggedOut: function(test) {
ct.getAndCall('/account', myCookie, function(data, res) {
test.ok(res.statusCode === 401);
test.done();
});
}
当测试运行时,执行会成功注销,然后通过调用authenticateSession
进入/account
,此时req.session.user
仍然存在!为什么!?
的更新 的
看起来这个问题与围绕cookie的app中间件直接相关。当我使用app.use(express.session())
代替app.use(express.cookieSession(...))
时,会话数据会被正确地吹走,我的测试也会通过。
答案 0 :(得分:1)
我明白了。显然,express.cookieSession(...)
意味着是一次性存储类型。后续请求可以访问最初设置的会话数据,但更改req.session对象不会保存新的会话数据。
为了解决这个问题,我转而使用express.session(...)
使用服务器端商店进行会话变量。