NodeJS + Express - 将会话中间件应用于某些路由

23

我有一个Express应用程序,其中有一些路由,只有其中两个需要支持会话。 我在各处都读到中间件定义(app.use(express.session({...))仅适用于它之后的路由,因此我创建了这个示例:

var express = require('express');
var app = express();
app.use(express.bodyParser());

app.get('/path1', function (req, res) {
    res.send('text response');
});


app.use(express.cookieParser());
app.use(express.session({
    secret: 'secret',
    cookie: { maxAge: new Date(Date.now() + 2 * 60 * 1000) }
}));


app.get('/path2', function (req, res) {
    res.session.test = { "test": "test" };
    res.send('text response');
});

app.listen(8088);

但是这样做不起作用:在 /path2 中,res.session 未定义。
如果我将 session 中间件的定义移到上面 - 一切正常,但是我发现当调用 /path1 时会创建会话(这是我想避免的)。

有人能解释一下如何让单个应用程序仅在某些路由中使用会话吗?

谢谢!

///// 更新 //////

经过更深入的挖掘 - 我找到了答案:

不要使用:app.use(express.session({ ... }));
而是定义以下内容:

var sessionMiddleware = express.session({
    //session configurations
});

function sessionHandler(req, res, next) { sessionMiddleware(req, res, next); }

然后在需要会话支持的特定路由上应用处理程序:

app.get('/path_that_need_session', sessionHandler, function (req, res) {                     
 /* Do somthing with req.session */  
});

2
为使您的回答更清晰,不妨将其编写为答案并接受它(这没关系)。对我来说,将会话隔离到特定路由中非常有效。谢谢。 - Shane Stillwell
2个回答

31

不要使用 app.use(express.session({ ... }))

相反,初始化会话中间件,保存对其结果函数的引用,然后在您想要使用它的路由中直接包含它。

var express = require('express'),
    app = express();

var session = express.session({
    //session configuration
});

app.use(app.router);


// must come after app.use(app.router);
app.get('/your/route/here', session, function(req, res){
    // code for route handler goes here
});

比更新中包含的答案稍微简单一点(不需要使用封装函数)。


谢谢!那正是我最终做的事情。 - alonkad
@Waylon_Flinn 我的路由被分成了不同的文件,我们如何扩展它以在不同的路由文件中公开会话? - pauljeba

1
问题实际上出在你的路由/path1,它是在使用express.session之前定义的。
当你在Express中声明一个路由处理程序时,此时router中间件(处理所有路由)将被插入到中间件链中。这意味着如果你还没有使用任何中间件来处理未来的路由(比如你的/path2处理程序),那么当处理任何路由时,它们将永远不会被调用。
如果你将/path1的处理程序移到app.use(express.session(...))之后,它将可以正常工作,而无需诡计。

如果我将 /path1 路由移动到 app.use(express.session(...)) 之后 - 它将使用会话(这正是我想避免的)。 - alonkad
我只想让 /path2 使用会话(它仅用于第一次身份验证)。/path1 的使用更广泛,不需要会话 - 所以我想节省会话开销(我将它们保存在数据库中)。 - alonkad
好的。我认为在你的情况下,你实际上可以省略sessionHandler函数,因为它所做的就是将参数委托给sessionMiddleware(因此你可以直接使用它)。 - robertklep

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接