如果您愿意,Express 中的会话将使用 cookie。它将交换用于在服务器端触发会话恢复的长密钥。
服务器端的会话数据不通过 cookie 与客户端共享。您可以在响应在服务器端启用会话的页面请求的标头中验证这一点。
Socket.IO 有能力在握手过程中恢复会话数据,因为它以正常的 HTTP 请求开始,并交换 cookie,用于验证用户身份以及用于会话恢复的另一个验证。
这是非常有效和安全的,因为被盗的 cookie 不会提供从另一个远程端点和浏览器访问的能力。
为了使不同的用户类型具有不同的访问限制,我使用了在路由声明中非常方便的中间件函数。
从编码的角度来看,它们可能看起来像这样:
var userTypes = {
any: function(types) {
return function(req, res, next) {
if (types.indexOf(req.session.user.type) != -1) {
return next();
} else {
return next(new Error('permission denied'));
}
}
},
is: function(type) {
return function(req, res, next) {
if (req.session.user.type == type) {
return next();
} else {
return next(new Error('permission denied'));
}
}
}
}
app.get('/items', userTypes.any([ 'developer', 'admin' ]), function(req, res, next) {
// will execute if user type is developer or admin
});
app.use(function(err, req, res, next) {
console.log(err);
res.send(err);
});
中间件与接受req、res和next的最后一个函数具有相同的功能,因此您可以从中访问会话数据,如果有效,可以调用next(),或next(new Error('reason'));不会将中间件链延续到最后一个函数,但会弹出处理错误的路由。
如果您有应该尝试回退的路由链,那么您可能希望在req 某处拥有allowed 的标志,而不是返回next(new Error());,然后检查最后一个路由回调以检查它是否为allowed如果不是,请致电next(),它将尝试找到适合查询的另一条路线。