[TypeORM] 로그인할 때 비밀번호 {select : false} 설정하여 보안 강화하기

sm·2023년 7월 12일
2

udemy

목록 보기
6/12
post-thumbnail
post-custom-banner

user.entity.ts

@Entity({ name: 'users' })
export class UserEntity {
 @PrimaryGeneratedColumn()
 id: number;

 @Column()
 email: string;

 @Column()
 username: string;

 @Column({ default: '' })
 bio: string;

 @Column({ default: '' })
 image: string;

 @Column({ select: false })
 password: string;
 
 ...

{select :false}를 설정하면, 해당 컬럼이 기본적으로 반한 결과에 포함되지 않도록 지정하는 역할을 한다.

비밀번호 필드에 select false를 설정하는 이유는 보안과 불필요한 데이터 노출을 방지하기 위해서이다.
비밀번호는 민감한 정보로, 보통은 클라이언트에게 반환되면 안 되는 데이터이다. 따라서, select false 옵션을 설정함으로써 기본적으로 비밀번호를 선택하지 않는다고 한다.

여태껏 비밀번호도 그냥 전부 다 return 했었는데.. 이를 알고나니까 또 새롭다.


이렇게 설정하면 기본적으로 데이터베이스 쿼리에서는 비밀번호 필드가 제외되어 반환되지 않는다. 그러나 로그인과 같이 비밀번호 필드값이 필요할 경우, 명시적으로 해당 필드를 선택해주어야 하는데,

user.service.ts

  async login(loginUserDto: LoginUserDto): Promise<UserEntity> {
    const user = await this.userRepository.findOne({
      where: {
        email: loginUserDto.email,
      },
      //필드 선택 - 비밀번호
      select: ['id', 'username', 'email', 'bio', 'image', 'password'],
    });

    if (!user) {
      throw new HttpException(
        'Credentials are not valid',
        HttpStatus.UNPROCESSABLE_ENTITY,
      );
    }
   
    //bcrypt로 비밀번호 compare
    const isPasswordCorrect = await compare(
      loginUserDto.password,
      user.password,
    );

    if (!isPasswordCorrect) {
      throw new HttpException(
        'Credentials are not valid',
        HttpStatus.UNPROCESSABLE_ENTITY,
      );
    }
  

    delete user.password; //password를 return 값에서 지움
    return user;
  }

select: ['id', 'username', 'email', 'bio', 'image', 'password']는 findOne 메서드에서 선택할 필드를 명시적으로 지정하면 된다.

여기서 password를 입력해주면 사용자가 입력한 비밀번호와 저장된 비밀번호를 비교할 수 있게 된다.

login 메서드에서는 로그인을 처리하고 유효성을 검사한 후, return 전에 delete user.password를 사용하여 비밀번호 필드를 삭제한 사용자 객체를 반환한다. 이를 통해 보안과 불필요한 데이터 노출을 방지할 수 있다!

profile
📝 It's been waiting for you
post-custom-banner

0개의 댓글