如何在Sequelize中的setterMethod之前运行模型验证?

dsc*_*ger 6 javascript coffeescript sequelize.js

我想保存一个哈希密码.我正在使用setterMethod:

module.exports = (sequelize, DataTypes) ->
  sequelize.define 'User',
    # other model fields [...]
    password:
      type: DataTypes.STRING
      validate: notEmpty: msg: 'You need to set a password.'
      set: (pw) ->
        salt = bcrypt.genSaltSync(10)
        hash = bcrypt.hashSync(pw, salt)
        @setDataValue('password', hash)
Run Code Online (Sandbox Code Playgroud)

setter首先运行.空字符串密码('')被散列为非空字符串(例如$2a$10$pDDIGnV.r47i9YOv0Fls/euQ0yYvfyq8T1SyP9VRQsTUAqptNmxXO).

验证器验证后,密码不再为空.

如何在setter之前验证密码?

我调查了钩子,但他们也没有提到制定者.

我正在使用sequelize@2.1.3.

dou*_*arp 1

我通过使用两个字段解决了这个问题,一个是VIRTUAL处理输入和验证的类型,另一个是STRING保存哈希密码的类型。

这个例子不是coffeescript,但你应该能够轻松翻译。

password_hash: {
  type: DatabaseTypes.STRING,
  allowNull: false,
  validate: {
    notEmpty: true,
  },
},
password: {
  type: DatabaseTypes.VIRTUAL,
  allowNull: false,
  // note that arrow functions cannot access "this", so use the form:
  set: function setPassword(val) {
    // trigger validation on "password" field
    this.setDataValue('password', val);

    // hash the password, this can be done in one step by passing the
    // number of salt rounds instead of the salt string.
    this.setDataValue('password_hash', bcrypt.hashSync(val, 10));
  },
  validate: {
    notEmpty: {
       message: 'You need to set a password.',
    },
  },
},
Run Code Online (Sandbox Code Playgroud)

当您对用户进行身份验证时,将输入的密码与 进行比较,User.password_hash而不是User.password.

instanceMethods: {
  // authenticate user given a password
  authenticate(password) {
    return bcrypt.compareSync(password, this.password_hash);
  },
},
Run Code Online (Sandbox Code Playgroud)

然后,您可以调用此实例方法来验证User.

User.findById(userId)
.then((user) => {
  if (user.authenticate(password)) {
    console.log('Authenticated');
  } else {
    console.log('Not authenticated');
  }
});
Run Code Online (Sandbox Code Playgroud)