在保存到数据库之前,我正在使用beforeCreate
加密密码。
当我这样做时:
const user = await User.create({name, email, password});
res.json(user);
我看到加密的密码作为回应。但是在数据库中,密码未加密。如果我执行user.reload()
然后发送,我会看到数据库中存储了什么(未加密的密码)。
这是模型:
User.init({
name: {
type: DataTypes.STRING,
allowNull: false
},
...
},{
sequelize,
hooks: {
beforeCreate: (user, options) => {
return bcrypt.genSalt(10)
.then(salt => {
bcrypt.hash(user.password, salt)
.then(hashedPassword => {
user.password = hashedPassword;
console.log(user.password, "FS");
return user.password;
})
.catch(err => console.log(err));
})
.catch(err => console.log(err));
}
}
})
这是控制器:
try{
const {name, email, password} = req.body;
if(isEmpty(name) || isEmpty(email) || isEmpty(password)){
res.status(400).json({errMessage: 'Enter name, email and password'});
}
const user = await User.create({name, email, password});
res.json(user); //data with encrypted password is sent, but not saved in db
}
答案 0 :(得分:0)
beforeCreate
钩子不需要返回值,该函数签名的返回值类型如下:
export type HookReturn = Promise<void> | void;
此外,您忘记在return
语句之前添加bcrypt.hash(user.password, salt)
,导致beforeCreate
函数不等待加密异步操作完成。
这是一个可行的示例:
import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';
import bcrypt from 'bcrypt';
class User extends Model {
password!: string;
name!: string;
}
User.init(
{
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
sequelize,
modelName: 'users',
hooks: {
beforeCreate: (user: User) => {
return bcrypt
.genSalt(10)
.then((salt) => {
return bcrypt
.hash(user.password, salt)
.then((hashedPassword) => {
user.password = hashedPassword;
})
.catch((err) => console.log(err));
})
.catch((err) => console.log(err));
},
},
},
);
(async function() {
try {
await sequelize.sync({ force: true });
await User.create({ name: 'ab', email: 'test@gmail.com', password: '123456' });
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
执行日志:
Executing (default): DROP TABLE IF EXISTS "users" CASCADE;
Executing (default): DROP TABLE IF EXISTS "users" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "users" ("id" SERIAL , "name" VARCHAR(255) NOT NULL, "email" VARCHAR(255) NOT NULL, "password" VARCHAR(255) NOT NULL, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'users' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "users" ("id","name","email","password") VALUES (DEFAULT,$1,$2,$3) RETURNING *;
检查数据库中的数据记录:
node-sequelize-examples=# select * from users;
id | name | email | password
----+------+----------------+--------------------------------------------------------------
1 | ab | test@gmail.com | $2b$10$XQb89m.b6ie8ImokS6JPdurWfIH4Cq19y.XGhb7LpWYUklp5jaYh2
(1 row)