强制Sequelize更新Express路由

时间:2015-11-06 05:20:35

标签: node.js express passport.js sequelize.js passport-local

我有一个非常简单的网站,使用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对象?

任何帮助将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:0)

//编辑:重写第一段更清晰

更改Instance对象中的任何列值时,还需要将更改显式保存到数据库以保留它们。由于您已经通过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部分。