Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何在插入前对密码进行哈希?_Node.js_Typescript_Nestjs_Dto_Typeorm - Fatal编程技术网

Node.js 如何在插入前对密码进行哈希?

Node.js 如何在插入前对密码进行哈希?,node.js,typescript,nestjs,dto,typeorm,Node.js,Typescript,Nestjs,Dto,Typeorm,我正在将Nest.Js与TypeORM一起使用,我想在将密码持久化到数据库之前对其进行哈希处理 我尝试使用事件装饰器@beforeinstert(),但它对我不起作用,但后来我发现它不起作用,因为我将DTO作为输入 user.controller.ts @Post() async create(@Body() data: CreateUserDto, @Res() res) { // if user already exist const isUserExist = a

我正在将Nest.Js与TypeORM一起使用,我想在将密码持久化到数据库之前对其进行哈希处理

我尝试使用事件装饰器@beforeinstert(),但它对我不起作用,但后来我发现它不起作用,因为我将DTO作为输入

user.controller.ts

  @Post()
  async create(@Body() data: CreateUserDto, @Res() res) {

    // if user already exist
    const isUserExist = await this.service.findByEmail(data.email);
    if (isUserExist) {
      throw new BadRequestException('Email already exist');
    }

    // insert user
    this.service.create(data);

    // send response
    return res.status(201).json({
      statusCode: 201,
      message: 'User added Successfully',
    });
  }


    create(data: CreateUserDto) {
        return this.userRepository.save(data)
    }
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly firstName: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly lastName: string;
    @IsNotEmpty()
    @IsString()
    @IsEmail()
    @ApiProperty()
    readonly email: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly password: string;
}

user.service.ts

  @Post()
  async create(@Body() data: CreateUserDto, @Res() res) {

    // if user already exist
    const isUserExist = await this.service.findByEmail(data.email);
    if (isUserExist) {
      throw new BadRequestException('Email already exist');
    }

    // insert user
    this.service.create(data);

    // send response
    return res.status(201).json({
      statusCode: 201,
      message: 'User added Successfully',
    });
  }


    create(data: CreateUserDto) {
        return this.userRepository.save(data)
    }
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly firstName: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly lastName: string;
    @IsNotEmpty()
    @IsString()
    @IsEmail()
    @ApiProperty()
    readonly email: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly password: string;
}

因此,我基本上是使用DTO来保存数据。这就是它不起作用的原因

但我要做的是将DTO映射到用户对象。所以,这就是我所做的

  @Post()
  async create(@Body() data: CreateUserDto, @Res() res) {

    // Create User object
    const user = new User();

    // Map DTO to User object
    for (const [key, value] of Object.entries(data)) {
      user[key] = value;
    }

    // if user already exist
    const isUserExist = await this.service.findByEmail(user.email);
    if (isUserExist) {
      throw new BadRequestException('Email already exist');
    }

    // insert user
    this.service.create(user);

    // send response
    return res.status(201).json({
      statusCode: 201,
      message: 'User added Successfully',
    });
  }

创建user.dto.ts

  @Post()
  async create(@Body() data: CreateUserDto, @Res() res) {

    // if user already exist
    const isUserExist = await this.service.findByEmail(data.email);
    if (isUserExist) {
      throw new BadRequestException('Email already exist');
    }

    // insert user
    this.service.create(data);

    // send response
    return res.status(201).json({
      statusCode: 201,
      message: 'User added Successfully',
    });
  }


    create(data: CreateUserDto) {
        return this.userRepository.save(data)
    }
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly firstName: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly lastName: string;
    @IsNotEmpty()
    @IsString()
    @IsEmail()
    @ApiProperty()
    readonly email: string;
    @IsNotEmpty()
    @IsString()
    @ApiProperty()
    readonly password: string;
}


有没有更好的方法?因为目前我必须在每个方法中编写代码来映射它。

这是一种有效的方法


您可以做的是从create方法提取这个逻辑,创建某种Builder对象,从DTO创建用户对象,反之亦然,并在需要的地方调用Builder

我首先将所有逻辑从我的控制器移动到服务中。这将允许您在其他地方重用该逻辑(如果有的话)(因为您更喜欢使用该服务类)

就个人而言,我会避免编写智能代码,因为这样可以节省2到3行代码。当你以外的其他人不得不审查/重构时,这将是一件痛苦的事。写些容易理解的东西就行了

第三,我会避免使用像beforeInsert这样的魔法。是的,这看起来很聪明,但你不清楚通行证是如何生成的

  • 如果您的实体具有与DTO相同的字段,那么拥有DTO的好处是什么。就个人而言,我会避免暴露实体的密码属性。相反,我在实体中有一个changePassword(generator:IUserPassGenerator)方法。至于检查通行证,我会有一些类似于verifyPass(validator:IPassChecker)的方法

  • 我要避免的另一件事是setter或公共道具,主要是因为它可能会导致您的实体进入无效状态。在您的情况下,例如,其他人可能会使用md5哈希更改密码属性。毕竟,他们甚至可以用一个未删除的字符串来更改它


  • 通过使用
    'Class-transformer'
    包,我们可以很容易地将
    普通对象文本
    映射到
    类实例

    答复:

    async create(@Body() data: CreateUserDto, @Res() res) {
    
    const user = plainToClass(User, data)
    
    }
    

    感谢您的快速回复,但您能否提供一个代码示例,因为我在实现它时遇到了问题。@BogdonUngureanu 1。)好的,我现在已经将逻辑放在服务中了。3.)我不知道为什么我不应该使用像BeforeInsert()这样的神奇东西。它是框架基础的一部分,为什么不使用它呢。4.)不,我的DTO与我的实体具有不同的属性,但即使它具有相同的属性,我也认为我需要使用它,因为我已经在DTO中应用了用于验证的约束。BeforeInsert和类似的东西用于扩展框架的行为,而不是应用程序逻辑。:)至于dto,我的建议是在您的实体上有一个接受该dto的工厂方法。我给你的建议是基于DDD原则的。这样想,如果不再维护nestjs会发生什么?如果您决定迁移到另一个框架,则必须重写所有内容。