Flash消息无法使用connect-session-sequelize

时间:2017-02-20 16:43:47

标签: node.js session sequelize.js flash-message

我有一个可以在MongoDB和Sequelize(PostgreSQL)之间切换的node.js网络应用程序。对于两者,我还在连接闪存(也尝试过快速闪存)中间件中进行闪存消息的分层。简而言之,MongoDB的工作原理,Sequelize没有。

该应用程序具有用户可以编辑的“包”概念。用户成功编辑包后,我设置了

的flash消息
"${timestamp} Package ${pkgID} successfully updated." 

并重定向。使用Sequelize(connect-session-sequelize),即使我可以在数据库中看到它,也不会显示flash消息,如果我刷新页面,那么出现。

以下是Sequelize会话的设置:

var cookieParser = require('cookie-parser');
var expSession = require('express-session');
var flash = require('express-flash');

app.use(cookieParser(process.env.COOKIE_SECRET));

if (sessionDBVendor === 'postgres') {
    let models = require('./models/postgres');
    var SequelizeSessionStore = require('connect-session-sequelize')(expSession.Store);
    var sequelizeSessionStore = new SequelizeSessionStore({
        db: models.sequelize,
        table: 'Session'
    });
    sequelizeSessionStore.on('set', function (data) {
        debug(`SequelizeSessionStore: Session ${data} UPDATED.`);
    });
    app.use(
        expSession({
            secret: process.env.COOKIE_SECRET,
            store: sequelizeSessionStore,
            resave: false, // we support the touch method so per the express-session docs this should be set to false 
            proxy: false, // if you do SSL outside of node.
            saveUninitialized: false,
        })
    );
}
app.use(flash());

查看connect-session-sequelize源代码,我发现我可以在我的DEBUG环境变量中添加“connect:session-sequelize”以在控制台中获取额外信息。以下是控制台日志的有趣部分,其中包含一些格式,一些空行和数字。

      connect:session-sequelize INSERT "DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI" +5s
    Executing (default): SELECT "sid", "userId", "expires", "data", "createdAt", "updatedAt" 
            FROM "webjmp"."sessions" AS "Session" 
            WHERE "Session"."sid" = 'DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI';
      connect:session-sequelize SELECT "DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI" +10ms
    Executing (default): SELECT "sid", "userId", "expires", "data", "createdAt", "updatedAt" 
            FROM "webjmp"."sessions" AS "Session" 
            WHERE "Session"."sid" = 'DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI';

(1)
    Executing (default): UPDATE "webjmp"."sessions" SET "expires"='2017-02-21 15:53:54.738 +00:00',
            "data"='{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
               "flash":{"flashSuccess":["{02/20/2017 10:53:49} Package 58a718a0280081343eeab6d9 was successfully updated."]}}',
            "updatedAt"='2017-02-20 15:53:54.756 +00:00' WHERE "sid" = 'DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI'

(2)
      connect:session-sequelize FOUND DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI with data 
         {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"flash":{}} +17ms

    Executing (default): SELECT "Package"."_id", "Package"."title", "Package"."description", 
            {content removed for brevity}
            FROM "webjmp"."packages" AS "Package" 
            {content removed for brevity}
            ORDER BY "Package"."timestamp" DESC;
    ::1 - - [20/Feb/2017:15:53:54 +0000] "POST /packages/58a718a0280081343eeab6d9 HTTP/1.1" 302 62
      packages ID of package in returned list: 58a718a0280081343eeab6d9 +166ms
      packages ID of package in returned list: 58a716c35326d0b0380c0b37 +0ms
      packages ID of package in returned list: 58a474c55c9f18cc31cb0e2a +0ms
      packages ID of package in returned list: 58a45dfa51f335c015d8591f +0ms
      packages ID of package in returned list: 589cc7f30a333d1864b07bb2 +0ms

(3)
      packages listPackages: flashSuccess: [] +0ms

      connect:session-sequelize TOUCH "DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI" +92ms
    Executing (default): UPDATE "webjmp"."sessions" SET "expires"='2017-02-21 15:53:55.023 +00:00',
            "updatedAt"='2017-02-20 15:53:55.024 +00:00' 
            WHERE "sid" = 'DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI'
    ::1 - - [20/Feb/2017:15:53:55 +0000] "GET /packages HTTP/1.1" 200 6909
      connect:session-sequelize SELECT "DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI" +14ms
    Executing (default): SELECT "sid", "userId", "expires", "data", "createdAt", "updatedAt" 
            FROM "webjmp"."sessions" AS "Session" 
            WHERE "Session"."sid" = 'DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI';
      connect:session-sequelize SELECT "DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI" +6ms
    Executing (default): SELECT "sid", "userId", "expires", "data", "createdAt", "updatedAt" 
            FROM "webjmp"."sessions" AS "Session" WHERE "Session"."sid" = 'DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI';

(4)
      connect:session-sequelize FOUND DnVIEQiTfaxKZjYgC7uHmKbelJvJBzrI with data 
            {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
            "flash":{"flashSuccess":["{02/20/2017 10:53:49} Package 58a718a0280081343eeab6d9 was successfully updated."]}} +3ms

请注意,在(1)处,UPDATE完成,在更新的“数据”中,“flash”包含一个对象:

"flash":{"flashSuccess":["{02/20/2017 10:53:49} Package 58a718a0280081343eeab6d9 was successfully updated."]}

这是我的flash消息。但是,请注意(2),connect-session-sequelize debug吐出一条FOUND消息,显示它找到的会话,并且在它显示的会话对象中,flash 为空

"flash":{}

就在那之后,在(3),我的代码尝试检索“flashSuccess”flash消息,但它出现了一个空数组。但是,在(4),connect-session-sequelize吐出另一个FOUND调试消息,并且其中有一条flash消息:

"flash":{"flashSuccess":["{02/20/2017 10:53:49} Package 58a718a0280081343eeab6d9 was successfully updated."]}

如果我检查数据库,那就是。

几乎就像设置flash消息的UPDATE是异步发生的,并且在(2)处检索会话时尚未完成,但之后它会显示出来。但我尝试在设置flash消息后抛出一个setTimeout(),但无济于事。

有什么想法在这里发生了什么?

更新:我添加了第三个会话存储选项,它使用connect-pg-simple中间件在PostgreSQL中存储会话。使用该选项,Flash消息可以正常工作。 connect-session-sequelize似乎是个奇怪的人。

1 个答案:

答案 0 :(得分:2)

在这里回答我自己的问题,但this table指出快递会话在这些flash消息场景中有竞争条件,并且需要在设置后调用req.session.save(cb) flash消息,返回回调中的响应,以避免这种情况。例如:

req.flash('flashError', err.message);
req.session.save(function() {
    res.redirect('/packages');
});

这样做解决了这个问题。