mysql - Sequelize:beforeCreate 挂钩不更新散列密码
问题描述
我正在尝试使用beforeCreate
钩子保存散列密码。但是,我生成的散列不会保存,而是保存纯文本版本。
这就是我的UserAuth
模型的样子
interface IUserAuthAttributes {
user_auth_id: number;
username: string;
password: string;
full_name: string;
disable_user: number;
user_level_id: number;
created_modified: string | Date;
}
interface IUserAuthCreationAttributes
extends Optional<IUserAuthAttributes, 'user_auth_id' | 'disable_user' | 'user_level_id' | 'created_modified'> {
username: string;
password: string;
full_name: string;
}
export class UserAuth
extends Model<IUserAuthAttributes, IUserAuthCreationAttributes>
implements IUserAuthAttributes {
public user_auth_id!: number;
public username!: string;
public password!: string;
public full_name!: string;
public disable_user: number;
public user_level_id!: number;
public created_modified: string | Date;
public toUserJSON: () => UserAuth;
public generateAccessToken: (payload: IUser) => string;
public generateRefreshToken: (payload: IUser) => string;
public passwordMatch: (pw: string, cb: (err: any, isMatch?: any) => void) => void;
public getRole: () => 'meter_reader' | 'evaluator' | null;
}
UserAuth.init({
user_auth_id: {
autoIncrement: true,
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
primaryKey: true
},
username: {
type: DataTypes.STRING(20),
allowNull: false,
defaultValue: ""
},
password: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: ""
},
full_name: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: ""
}
// ... other
},
{
sequelize: DBInstance,
tableName: 'user_auth',
timestamps: false,
});
这就是我定义钩子的方式:
UserAuth.beforeCreate((user, option) => {
const salt = bcrypt.genSaltSync();
// Using hashSync throws an error "Illegal arguments: undefined, string"
// const hash = bcrypt.hashSync(user.password, salt);
bcrypt.hash("password", salt, (err, hash) => {
if (err) throw new Error(err.message);
console.log('HASH -------', hash);
user.password = hash;
});
});
当我创建用户时:
const { username, password, full_name } = req.body;
const user = await UserAuth.create({
username, password, full_name
});
将散列值记录到控制台后,我确实成功生成了一个
HASH ------- $2a$10$KN.OSRXR7Od8WajjuD3hyutqk1tGS/Be.V9NDrm3F7fyZWxYAbJ/2
解决方案
终于找到了解决办法。
在我之前的代码中,我使用回调来生成盐和哈希。同样从前面的代码
const hash = bcrypt.hashSync(user.getDataValue('password'), salt);
它抛出一个错误Illegal arguments: undefined, string
,因为user.password
从实例返回未定义,所以相反,我使用getDataValue
实例的方法获取密码的值,然后使用setDataValue
设置散列密码而不是使用赋值操作user.password = hash
UserAuth.beforeCreate((user, option) => {
if (user.isNewRecord) {
const salt = bcrypt.genSaltSync();
const hash = bcrypt.hashSync(user.getDataValue('password'), salt);
// user.password = hash; Not working
user.setDataValue('password', hash); // use this instead
}
})
推荐阅读
- php - 致命错误:未捕获的错误:在 bool 上调用成员函数 bindParam()
- flutter - 如何在映射列表中等待未来
- spring-boot - Spring Security OAuth 2 - 授权服务器从 0.1.0 更新到 0.1.1 / 0.1.2 使示例项目不起作用
- databricks - 如何使用 Databricks 社区版将从 Kaggle 下载的数据导入 DBFS?
- gams-math - GAMS中集合的变量定义问题
- xpath - XPath:获取带有和不带有标签的案例的基础文本
- flutter - 类颤振SQFlite内的实例变量初始化
- rust - syn 获取平面令牌流
- node.js - 如果我尝试在父级迭代中迭代哈巴狗,则无法读取未定义的属性“长度”
- android - 在 recyclerview 适配器中使用 ViewBinding 奇怪地显示项目?