jongviet

Feb 10, 2021 - nestjs 포인트들2 본문

node, express, nestjs

Feb 10, 2021 - nestjs 포인트들2

jongviet 2022. 2. 10. 22:01

*2월10일

 

 

*DTO 통한 모델링

-DB에서 얻은 데이터를 service나 controller로 보낼 때 사용 하는 객체. nestjs에서는 클래스를 이용해서 구성하는 것을 권장함
-데이터 유효성 체크에 효율적!
 
파라미터로 들어오는 값의 형태를 미리 class를 사용하여 정의하고 그 형태로만 값을 주고 받는 것
 
export class CreateBoardDto {
  title: string;
  description: string;
}
 
*pipe란?
-@injectable() 데코레이터가 달린 클래스임. 데이터 변환과 유효성검사를 위해 사용 됨
 
-string -> number 변환 또는 param 길이 등~
 
-종류는 총 3가지, handler level, parameter level, global level
->즉 핸들러 전체, 파라미터 하나 또는 어플리케이션 전체에 대한 파이프 역할을 함!
 
-기본 내장형 파이프는 validation, parseInt, parseBool, parseArray, parseUUID, defaultValue파이프 등이 있음!

 

*커스텀 에러 문구 처리

 if (!found) {
    throw new NotFoundException(
      `요청하신 게시물을 찾을 수 없습니다. [요청 게시물 id : ${id}]`,
    ); // 커스텀 에러 문구 처리~
  } // 못 찾을 시 예외 처리
 
  return found;
}

 

*ORM용 @entity wrapped class

-@entity로 감싸진 클래스는 해당 클래스가 엔티티임을 나타낼 때 사용됨

-즉 데이터베이스 특정 테이블과 매핑 되는 형태라는 것.

-그 중 @PrimaryGeneratedColumn은 PK, @column은 일반 값

 

 

*typeORM remove와 delete의 차이..?

-remove는 존재하는 아이템만 삭제, 즉 존재하는지 점검 -> 삭제
-delete는 만약 아이템이 존재하면 지우고 아니면 아무런 동작 안함 따라서 한번만 접근해도 됨

 

 

*class-validator를 통해서 DTO 유효성 검사 체크
export class AuthCredentialDto {
  @IsString()
  @MinLength(4)
  @MaxLength(20)
  username: string;
 
  @IsString()
  @MinLength(4)
  @MaxLength(20)
  @Matches(/^[a-zA-Z0-9]*$/, { message: 'only eng and number are acceptable' }) // 정규식도 활용 가능
  password: string;
}

 

*기존에 존재하는 유저에 대한 try & catch 에러 처리
 
@EntityRepository(User)
export class UserRepository extends Repository<User> {
  async createUser(authCredentialDto: AuthCredentialDto): Promise<void> {
    const { username, password } = authCredentialDto;
    const user = this.create({ username, password });
 
    try {
      await this.save(user); // typeORM으로 DB 저장
    } catch (error) {
      if (error.code === '23505') {
        throw new ConflictException(`existing username!!`);
      } else {
        throw new InternalServerErrorException();
      }
    }
  }
}
 

*암호화 처리 bcryptjs lib

->원본 데이터 저장은 가장 최악, 개인정보 관리부실로 소송임...
->양방향 암호화는, 암호화된 키가 노출되면 쉽게 복호화 되서 노출됨…
 
->sha256등으로 해시해서 저장(단방향),, 복호화는 불가능함!! -> 레인보우 테이블로 뚫을 수 있음..
->결국 대안이 salt + pwd -> unique hashed pwd

 

 

*bcryptjs lib로 솔트 암호화 처리하여 회원가입
import * as bcrypt from 'bcryptjs’;
 
const { username, password } = authCredentialDto;
const salt = await bcrypt.genSalt(); // 랜덤 솔트 생성
const hashedPassword = await bcrypt.hash(password, salt); // 솔트와 패스워드 해시화
const user = this.create({ username, password: hashedPassword });

 

*로그인 시 솔트 암호화된 비밀번호 검증
async signIn(authCredentialDto: AuthCredentialDto): Promise<string> {
  const { username, password } = authCredentialDto;
  const user = await this.userRepository.findOne({ username });
 
  if (user && (await bcrypt.compare(password, user.password))) {
    return 'ok';
  } else {
    throw new UnauthorizedException('nok');
  }

 

}

 

 

Comments