Sequelize: beforeCreate 挂钩不更新散列密码
Sequelize: beforeCreate hook not updating hashed password
我正在尝试使用 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 ------- a$KN.OSRXR7Od8WajjuD3hyutqk1tGS/Be.V9NDrm3F7fyZWxYAbJ/2
终于找到解决办法了。
在我之前的代码中,我使用回调来生成盐和哈希。同样来自之前的代码
const hash = bcrypt.hashSync(user.getDataValue('password'), salt);
它抛出错误 Illegal arguments: undefined, string
因为 user.password
returns 未在实例中定义,所以我使用 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
}
})
我正在尝试使用 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 ------- a$KN.OSRXR7Od8WajjuD3hyutqk1tGS/Be.V9NDrm3F7fyZWxYAbJ/2
终于找到解决办法了。
在我之前的代码中,我使用回调来生成盐和哈希。同样来自之前的代码
const hash = bcrypt.hashSync(user.getDataValue('password'), salt);
它抛出错误 Illegal arguments: undefined, string
因为 user.password
returns 未在实例中定义,所以我使用 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
}
})