【问题标题】:waterline 0.10.14 + express - beforeCreate not executing水线 0.10.14 + express - beforeCreate 未执行
【发布时间】:2014-11-27 17:57:06
【问题描述】:

我试图在我的用户模型上设置密码,但在调用 create 之前从未见过。

使用 Express 4.2 和 waterline 0.10.14。

用户模型:

var Waterline = require('waterline'),
    uuid = require('uuid'),
    bcrypt = require('bcrypt');

var User = module.exports = Waterline.Collection.extend({

  identity: 'user',
  connection: 'default',
  autoPK: false, // prevents creation of the id
  schema: true,


  types: {
    // Custom Validation - https://github.com/balderdashy/waterline-docs/blob/master/models.md#custom-validations
  },

  attributes: {

    uuid: {
      type: 'uuidv4',
      primaryKey: true,
      defaultsTo: uuid.v4
    },

    first_name: {
      type: 'string',
      required: true
    },

    last_name: {
      type: 'string',
      required: true
    },

    email: {
      type: 'email',
      required: true,
      unique: true
    },

    username: {

      // TODO: validate no spaces, or special characters

      type: 'string',
      required: true,
      unique: true,
      index: true,
      minLength: 3,
      maxLength: 30
    },

    password: {
      // TODO:  add rules on password
      type: 'string',
      minLength: 6,
      maxLength: 50,
      required: true,
      columnName: 'encrypted_password'
    },

    // TODO: custom input with - https://developers.google.com/places/documentation/autocomplete#place_autocomplete_requests
    location: {
      type: 'string'
    },

    activated: {
        type: 'boolean',
        defaultsTo: false
    },
    activationToken: {
        type: 'string'
    },

    // Override toJSON instance method to remove values
    toJSON: function() {
      var obj = this.toObject();
      // delete obj.password;
      delete obj.email;
      delete obj.activated;
      delete obj.activationToken;

      return obj;
    },


    verifyPassword: function (password) {
      return bcrypt.compareSync(password, this.password);
    },

    changePassword: function(newPassword, next){
      this.password = newPassword;
      this.save(function(err, u) {
        return next(err,u);
      });
    },


    // Lifecycle Callbacks
    beforeCreate: function(attrs, next) { 

      console.log('beforeCreate - user');

      bcrypt.genSalt(process.env.SALT_WORK_FACTOR, function(err, salt) {
          if (err) return next(err);

          bcrypt.hash(attrs.password, salt, function(err, crypted) {
            if(err) return next(err);

            attrs.password = crypted;
            attrs.activationToken = crypto.token(new Date().getTime() + attrs.email);

            return next();
          });
        });

    },

    beforeUpdate: function (attrs, next) {
      if(attrs.newPassword){
        bcrypt.genSalt(process.env.SALT_WORK_FACTOR, function(err, salt) {
          if (err) return next(err);

          bcrypt.hash(attrs.newPassword, salt, function(err, crypted) {
            if(err) return next(err);

            delete attrs.newPassword;
            attrs.password = crypted;
            return next();
          });
        });
      }
      else {
        return next();
      }
    }


  }

});

这就是它在我的控制器上的调用方式。

exports.create = function (req, res, next) {
    app.models.user.create(req.body, function (err, model) {
        if(err) return res.error('users/signup', err);
        res.success('users/welcome', model);
    });
};

我从未在调用 beforeCreate 时看到过日志,并且从未对密码进行哈希处理。想法?

编辑:反映最新变化的用户模型。还注意到 beforeCreate 应该在验证之前运行。

【问题讨论】:

  • 我在使用sails 0.10.5时遇到了同样的问题

标签: node.js express sails.js waterline


【解决方案1】:

我想我知道为什么你的 beforeCreate 没有运行。这是因为密码是必填字段。 Waterline 在运行 beforeCreate 回调之前实际上运行了 validate 回调。由于在创建 values.password 之前密码不存在,因此验证失败并且 beforeCreate 永远不会被调用。我假设您在创建新用户时只是传递了一个 newPassword 参数。

【讨论】:

  • 这是一个简单的修复。可悲的是。刚刚在我的属性对象中有生命周期回调。
【解决方案2】:

这是我的一个小错误,将生命周期回调封装在与我的属性相同的对象中。它们必须在该对象之外。

【讨论】:

  • 为我节省了几个小时。谢谢:)
猜你喜欢
  • 1970-01-01
  • 2014-02-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多