Nestjs: проверка пароля пользователя для входа — Ошибка: требуются аргументы данных и соли

#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);
    }); 
};