【问题标题】:How to check if a specific field was sent on sequelize's hooks?如何检查是否在 sequelize 的钩子上发送了特定字段?
【发布时间】:2019-02-04 02:04:48
【问题描述】:

我在我的用户模型上使用 beforeUpdate 钩子在密码更改时对密码进行哈希处理。但是只要发送任何字段,它就会更改密码。如何在返回钩子函数之前检查密码是否已发送?

我尝试将退货放在if(user.password !== '') 中。但它不起作用,可能是因为它引用了存储的密码。

这是我的代码:

const Sequelize = require('sequelize')
const connection = require('../../../db/connection.js')

const bcrypt = require('bcrypt')

const User = connection.define('user', {
  fullName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  email: {
    type: Sequelize.STRING,
    allowNull: false,
    unique: true,
    validate: { isEmail: true }
  },
  password: {
    type: Sequelize.STRING,
    allowNull: false
  }
})

// Create hash for password, on before create, using bcrypt
User.beforeCreate((user, options) => {
  return bcrypt.hash(user.password, 10).then(hash => {
    user.password = hash
  })
})

// Create hash for password, on before update, using bcrypt
User.beforeUpdate((user, options) => {
  return bcrypt.hash(user.password, 10).then(hash => {
    user.password = hash
  })
})

module.exports = User

【问题讨论】:

  • 嗨,你能解决这个问题吗?

标签: node.js sequelize.js


【解决方案1】:

执行此操作的正确方法是在模型定义中使用afterValidate 挂钩,如下所示 -

// Create hash for password, on before create/update, using bcrypt
User.afterValidate((user) => {
  user.password = bcrypt.hashSync(user.password,10);
})

调用钩子的顺序 -

(1)
  beforeBulkCreate(instances, options)
  beforeBulkDestroy(options)
  beforeBulkUpdate(options)
(2)
  beforeValidate(instance, options)

[... validation happens ...]

(3)
  afterValidate(instance, options)
  validationFailed(instance, options, error)
(4)
  beforeCreate(instance, options)
  beforeDestroy(instance, options)
  beforeUpdate(instance, options)
  beforeSave(instance, options)
  beforeUpsert(values, options)

[... creation/update/destruction happens ...]

(5)
  afterCreate(instance, options)
  afterDestroy(instance, options)
  afterUpdate(instance, options)
  afterSave(instance, options)
  afterUpsert(created, options)
(6)
  afterBulkCreate(instances, options)
  afterBulkDestroy(options)
  afterBulkUpdate(options)

更多详情here

【讨论】:

  • 如果密码没有更新,这不会再次散列之前的密码散列吗?
【解决方案2】:

你可以这样使用它:

User.beforeCreate((user, options) => {
    // user.password // Will check if field is there or not
    // user.password != "" // check if empty or not
    user.password = user.password && user.password != "" ? bcrypt.hashSync(user.password, 10) : "";
})

【讨论】:

  • 你不是说 User.beforeUpdate 吗?我测试了它,它也不起作用。当密码未在 PUT 上发送时,密码仍在更改。我认为这是因为 user.password 指的是已经存储的密码,并且它总是返回 true。所以它所做的就是创建一个散列的散列。
猜你喜欢
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2021-03-13
  • 2022-09-30
相关资源
最近更新 更多