【问题标题】:Express Set Session for Specific Routes特定路线的快速设置会话
【发布时间】:2017-02-08 19:32:20
【问题描述】:

我试图仅包含某些路由(身份验证路由)的会话,但由于错误页面路由,我遇到了问题:

我有这个:

    app.use(session({
        secret: config.secrets.session,
        saveUninitialized: false,
        resave: false,
        store: sessionStore,
        proxy: true,
        cookie: {
            maxAge: config.token_duration,
            secure: false
        }
        // rolling: false
    }));


    app.use('/api/user', require('./api/user'));
    app.use('/api/auth', require('./api/auth'));  

    app.route(['/error/500','/error/404','/user/settings'])
        .get((req, res) => {
            res.sendFile(path.resolve(app.get('appPath') + '/index.html'));
        });

    app.route('/*/*')
        .get(errors[404]);       

    app.use(errors[500]); 

所以,如果我这样使用它,我的应用程序中的所有页面都会创建一个会话(我不想要)。如果我在错误路由之后移动会话部分,我将永远不会到达 api 路由,因为它将到达 404 路由。

提前致谢

【问题讨论】:

    标签: node.js express routing express-session


    【解决方案1】:

    中间件只能与某些路由相关联,并且指定的顺序很重要。有多种方法可以做到这一点,如何最好地实现它取决于您的网站使用的路径,以及如何最轻松地在路径之间创建链接,以及它是否应该有会话中间件。

    要做的一件简单的事情是将错误路由处理程序放在会话中间件之前。然后,这些路由处理程序将首先“处理”请求,并且永远不会调用会话中间件。

    app.route(['/error/500','/error/404','/user/settings'])
        .get((req, res) => {
            res.sendFile(path.resolve(app.get('appPath') + '/index.html'));
        });
    
    app.use(session({
        secret: config.secrets.session,
        saveUninitialized: false,
        resave: false,
        store: sessionStore,
        proxy: true,
        cookie: {
            maxAge: config.token_duration,
            secure: false
        }
        // rolling: false
    }));
    

    你可以做的其他事情:

    1. 在您的会话中间件上放置一个路径,以便仅针对您网站中的某些路径调用它(所有经过身份验证的页面都应位于该路径下方)。

    2. 创建您自己的中间件处理程序,检查路径是否为/error,如果不是,则调用会话中间件处理程序。如果是/error,则不要调用会话中间件。

    最后一个可以这样完成:

    const sessionHandler = session({
        secret: config.secrets.session,
        saveUninitialized: false,
        resave: false,
        store: sessionStore,
        proxy: true,
        cookie: {
            maxAge: config.token_duration,
            secure: false
        }
        // rolling: false
    });
    
    app.use(function(req, res, next) {
        // if path does not start with /error/, then invoke session middleware
        if (req.url.indexOf("/error/") !== 0) {
            return sessionHandler(req, res, next);
        } else {
            next();
        }
    });
    

    【讨论】:

    • 我使用了你的第一种方法,效果很好!我已经尝试过你的最后一种方法,但由于我使用的是安全中间件 (github.com/krakenjs/lusca),我不得不调用“app.use(session...”而不是将其保存在变量中。谢谢!
    • @Bernardo - 您可以将其保存在变量中。我不知道你为什么认为那行不通。在app.use(session(...)) 中,session() 部分仅在应用启动时执行一次,并返回app.use() 使用的新中间件函数。这正是我的sessionHandler 示例所做的。同样的事情。
    • 是的,我想当我尝试分配变量时犯了一个错误
    • 请注意,在第二个示例中,如果您有后续调用的中间件,则必须在 if 块之外调用 next()。我相信session() 会隐式调用next() 处理路由。
    • @stephenmc - 你是对的。我已经编辑修复。谢谢。
    【解决方案2】:

    您还可以使用 Express.router() 链接/组合多个中间件,如本示例中所述:Express: composing middleware

    然后将该组合路由器(链式中间件)应用为特定的路由处理程序。

    【讨论】: