#authentication #mongoose #nestjs #bcrypt #salt
#аутентификация #мангуст #nestjs #bcrypt #соль
Вопрос:
Я пытаюсь проверить пароль пользователя и использую nestjs, mongoose и bcrypt. Я получаю Error: data and salt arguments required
, когда ввел неправильный пароль. Функция validatePassword заключается в сравнении соответствия пароля пользователя и хэша. Может кто-нибудь, пожалуйста, дайте мне знать, где я допустил ошибку?
auth.service.ts
@Injectable()
export class AuthService {
constructor(@InjectModel('Users') private usersModel: Model<UserDocument>) {}
async signIn(authCredential: AuthCredentialDto) {
const {username, password} = authCredential;
const userFound = await this.usersModel.findOne({username});
const user = new User();
if (userFound amp;amp; (await user.validatePassword(password))) {
return user.username;
} else {
return null;
}
}
private async hashPassword(password: string, salt: string): Promise<string> {
return bcrypt.hash(password, salt);
}
}
user.schema.ts
export type UserDocument = User amp; Document;
@Schema()
export class User {
@Prop()
id: string;
@Prop({
unique: true,
})
username: string;
@Prop()
password: string;
@Prop()
salt: string;
async validatePassword(password: string): Promise<boolean> {
const hash = await bcrypt.hash(password, this.salt);
return hash === this.password;
}
}
export const UserSchema = SchemaFactory.createForClass(User);
auth.controller.ts
@Post('signin')
@ApiOperation({
operationId: 'signin user',
summary: 'Create company profile',
})
async signIn(@Body(ValidationPipe) authCredentialDto: AuthCredentialDto) {
return this.authService.signIn(authCredentialDto);
}
Комментарии:
1. хэш-функция неправильно получает соль
Ответ №1:
Из моего опыта использования библиотеки bcrypt, но применимо только в том случае, если вам абсолютно не нужно хранить соль отдельно от вашего пароля. Нет необходимости сохранять соль извне при передаче числа в хеш-функцию. Это сгенерирует соль с указанным количеством раундов. Вместо повторного хеширования пароля вы можете использовать функцию сравнения bcrypt только с открытым текстом и хэшем без необходимости сначала получать соль.
Ответ №2:
Попробуйте функцию bcrypt.compare, которая не нуждается в соли. Пример кода, который сработал для меня :
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
import * as bcrypt from 'bcrypt';
export type UserDocument = User amp; Document;
@Schema()
export class User {
@Prop()
username: string;
@Prop({required: true})
password: string;
checkPassword: Function;
}
UserSchema.methods.checkPassword = function(attempt, callback) {
let user = <UserDocument>this;
bcrypt.compare(attempt, user.password, (err, isMatch) => {
if(err) return callback(err);
callback(null, isMatch);
});
};