强制 Sequelize 在 Express 路由中更新 req.user

Forcing Sequelize to update req.user in Express route

我有一个非常简单的站点,它使用 Passport JS 创建本地登录策略以使用 Sequelize ORM 访问本地 postgres 数据库。

用户模型看起来像这样:

module.exports = function(sequelize, DataTypes) {
    return sequelize.define('user', {
        id: {
            primaryKey: true,
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4
        },
        email: DataTypes.STRING,
        password: DataTypes.STRING,
    }, {
        classMethods: {
            generateHash: function(password) {
                return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
            },
        },
        instanceMethods: {
            validPassword: function(password) {
                return bcrypt.compareSync(password, this.password);
            }
        },
        getterMethods: {
            someValue: function() {
                return this.someValue;
            }
        },
        setterMethods: {
            someValue: function(value) {
                this.someValue = value;
            }
        }
    });
}

似乎一切正常。我可以使用此策略注册、登录并查看数据。

我也在使用 Express 并设置了各种路线。 req.user 似乎设置正确,因为我可以与该对象的所有字段进行交互。

考虑正确运行的示例路线:

app.get('/profile', isLoggedIn, function(req, res) {
    res.render('profile.ejs', {
        user : req.user
    });
});

我的序列化/反序列化方式:

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
    User.findById(id).then(function(user) {
        done(null, user);
    }).catch(function(e) {
        done(e, false);
    });
});

因此,根据 Passport JS 文档,用户会话似乎已正确设置并连接到 Express。

问题是我无法更新用户对象中的任何字段。

如果我有以下路线:

app.get('/change-email', function(req, res) {
    req.user.email = req.body.email;
    res.status(200).end();
});

数据库中没有任何反应。

这与 this question 非常相似,只是它与 Sequalize 一起出现,用户对象永远不会保留,即使在注销并重新登录后也是如此。

我也试过:req.session.passport.user.email = req.body.email

虽然我不认为这会解决问题,但我也尝试用新的用户对象调用 login,但这产生了 500 个错误。根据 Passport JS 文档,可以调用的函数数量有限,我开始怀疑这个功能是否可行。

我不确定从这里可以尝试什么。如何使用 Sequelize 更新我的 user 对象?

如有任何帮助,我们将不胜感激!谢谢!

// 编辑:重写第一段以便更清楚

当您更改实例对象中的任何列值时,您还需要明确地将更改保存到数据库以持久保存它们。由于您已经通过 passport.deserializeUser 将用户实例存储在 req.user 中,因此您只需对路由代码进行少量更改即可。

我建议:

而不是您当前 /change-email 的路线
app.get('/change-email', function(req, res) {
  req.user.email = req.body.email;
  req.user.save()
  .then(function() {
    res.status(200).end();
  });
});

有关如何将更改保存到实例的更多信息,请参阅 Sequelize 文档的 this 部分。