我的应用程序通常有中间件堆栈:
app.configure(function() {
app.use(express.static(PUBLIC_DIR));
app.use(express.favicon());
app.use(express.bodyParser({
keepExtensions: true,
uploadDir: '/tmp/neighr'
}));
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
secret: '***REDACTED***',
store: sessionStore,
}));
app.use(express.csrf());
app.use((require('connect-flash'))());
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
app.locals({
_csrf: req.session._csrf,
url: req.url,
user: req.user,
authenticated: req.isAuthenticated(),
messages: {
info: req.flash('info'),
error: req.flash('error'),
success: req.flash('success')
}
});
next();
});
app.use(app.router);
app.use(express.logger());
app.use(express.errorHandler());
});
正如您所看到的,express.static
是堆栈中的第一个,因此静态资源将在不经过整个会话的情况下提供,只会使加载时间更长。
但是,我确实有一些动态数据,我希望在没有会话的情况下提供服务:
app.get('/avatar/:id', function(req, res) {
var fid = res.params.id;
/* load binary from database */
res.send(data);
});
此路由位于堆栈末尾的app.router
内。我想继续声明这个和其他路由,但是如何在会话中间件之前使用express来解析这些?
将来可能会有更多这样的动态路线,参数更多。
答案 0 :(得分:6)
一旦声明了路由,Express会在此时将router
中间件插入中间件堆栈,因此如果您在加载会话中间件之前声明单个路由,所有路由请求会跳过会话中间件:
app.get('/one', ...); // inserts `app.router` into the stack at this point
app.use(express.session(...));
app.get('/two', ...); // will skip the session middleware
我能想到两个解决方案:创建自己的中间件来处理不应该通过会话中间件传递的请求,或者为要通过它运行的每个路由显式设置会话中间件。
第一个解决方案:
app.use(function(req, res, next) {
if (req.path.indexOf('/avatar/') === 0) {
// parse out the `id` and return a response
}
next();
});
这显然不是很灵活。
第二个解决方案:
// instantiate the session middleware:
var sessionMiddleware = express.session(...);
// default setup: insert the router before the session middleware:
app.use(app.router);
app.use(sessionMiddleware);
// Pass it explicitly to the route:
app.get('/two', sessionMiddleware, function(req, res) {
...
});
在您使用Passport的情况下,您可能需要一组中间件:
var authMiddleware = [
express.session(...),
passport.initialize(),
passport.session()
];
app.get('/two', authMiddleware, ...);
看看Express是如何实现的,我认为不可能实例化第二个路由器(并使其正常运行)。