Body 데이터 잘 넘어오는 지 확인
회원가입을 하기위해서는 보통 email / 비밀번호 정도의 데이터를 전달 받게 되는데, 메소드 파라메터를 입력하는 곳에서 @Body() 데코레이터로 가져올 수 있다.
이 데코레이터를 통해서 가입정보가 잘 넘어오는지 테스트 해보자.
postman test
→ POST 메소드로 email/name/password 를 json형태로 전달하는 테스트를 진행하고, 통신은 성공이라는 메시지를 받았다.
로그를 확인해보자.
로그 확인
키와 밸류값이 잘 넘어온 것을 확인할 수 있다.
하지만 현재 구조에서의 문제점은
회원가입시 email/name/password 항목이 다 필요한 로직에서 email 필드가 빠지면 예외처리가 되어야 되는데, 그냥 통신이 통과를 한다는 것이다.
형식에 맞지않는 요청데이터가 들어올 때 예외처리가 필요하다.
Request DTO 만들기
폴더 / 파일 생성
cats 도메인 폴더 내부에
dto 폴더를 만들어서 cats.request.dto.ts 를 관리하자
cat.request.dto.ts 정의
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
export class CatRequestDto {
@IsEmail()
@IsNotEmpty()
email: string;
@IsString()
@IsNotEmpty()
password: string;
@IsString()
@IsNotEmpty()
name: string;
}
JavaScript
복사
이렇게 해당 파일을 정의하고 요청데이터의 타입을 명시해주면 된다.
cats.controller.ts > signUp()
위처럼 body의 타입을 CatRequestDto 로 명시한다.
이제 가입필수정보에서 하나라도 빠지게 되면 예외처리가 진행이 될 것이다.
예외처리 확인
위와 같이 의도적으로 email정보를 누락 시켰을 때,
아래 응답데이터에서 email정보가 비어서는 안되고, 형태 또한 이메일이어야 된다는 메시지가 반환되었다.
에러 메시지 형태가 배열형태로 왔다는거 기억하자.
Service 비즈니스 로직 구현
controller - service 바인딩
CatsController 내부에는 CatsService가 의존성이 추가된 상태이어야 한다.
그리고 signUp에 대해서 서비스 로직을 바인딩 한다.
서비스 로직에서는 여러가지 역할을 수행하는데
→ 요청데이터 유효성 검사
→ 비밀번호 암호화
→ DB저장
등의 역할을 한다.
DB에 저장을 할려면 쿼리를 사용해야 되는데,
스키마를 서비스안에서 사용하기 위해서는 DI를 해줘야 된다
스키마 의존성 주입
constructor(@InjectModel(Cat.name) private readonly catModel: Model<Cat>) {}
JavaScript
복사
Cats 스키마를 CatsService에서 사용을 하기 위해서는 의존성 주입을 해야되는데, 하는 방법은 위와 같다.
모듈에도 추가해야된다. - cats.module.ts
imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
JavaScript
복사
CatSchema를 CatModule에 추가해줘야된다. 그래야 사용이 가능하다.
SignUp 비지니스 로직
요청 데이터 (body) 구조 분해 할당
signUp(body: CatRequestDto) {
const { email, name, password } = body;
}
JavaScript
복사
이렇게 body데이터 안에 email, name, password 키값이 있다면,
구조분해할당 문법으로 꺼내 쓸 수 있다.
이메일 중복 검증
→ calModel.exists({ email }); : 에서 email 중복 체크를 하는 쿼리가 내장되어 있다.
→ if 문에서 중복이 된다면 예외처리를 해주면 되는데, UnauthorizedException 을 사용하면 403 상태코드가 포함되어 예외처리가 된다.
패스워드 암호화
패스워드 암호화는 bcrypt를 사용하면 되고, 이를 위해서는 설치를 해줘야 된다.
1.
설치
npm i bcrypt
npm i -D @types/bcrypt
JavaScript
복사
2.
import
bcrypt를 import를 먼저 한다.
3.
사용
이렇게 bcrypt.hash함수를 사용하면 된다.
여기서 10은 해싱 알고리즘의 솔트 라운드(salt rounds)를 나타낸다. 이 숫자는 해싱 과정에서 추가적인 복잡성을 더하는 역할을 하며, 값이 클수록 속도는 느려지지만 보안성이 증가한다.
일반적으로 10에서 12사이의 값을 많이 사용한다.
DB 저장
const cat = await this.catModel.create({
email,
name,
password: hashedPassword,
});
JavaScript
복사
email 이나 비밀번호처럼 보안과 중복을 위한 데이터를 처리하면,
DB에 저장을 하면 된다.
저장을 할 때는 catModel에 내장된 create함수를 사용하면 된다.
cats.controller.ts
완성된 서비스 로직을 컨트롤러랑 연결한다.
비동기 작업이니까 await - async를 달아줘야 된다.
postman 테스트
이렇게 통신은 정상적으로 작동하고, 비밀번호가 암호화 된 것도 확인 가능
ID 또한 몽고디비가 만들어 준것이 확인 가능
생성 업데이트 시간 또한 module에 추가된대로 작동 확인
DB 확인
몽고디비 compass에 들어가보면 데이터가 잘 들어간 것을 확인 할 수 있다.
가상화 필드 (virtual)
사실 위처럼 전체 데이터를 반환해주면 비밀번호가 노출된 것이나 다름이 없다.
그래서 스프링에서 사용했던 응답DTO처럼 민감한 정보는 숨겨야 된는데, 그를 위해서 사용하는 것이
virtual 필드 이다.
사용
readonly readOnlyData: { id: string; email: string; name: string };
JavaScript
복사
CatSchema.virtual('readOnlyData').get(function (this: Cat) {
return {
id: this.id,
email: this.email,
name: this.name,
};
});
JavaScript
복사
이렇게 스키마 내부에 virtual필드를 사용해서 반환해주고 싶은 데이터의 형태를 정해준다.
여기서 필요없는 데이터 민감한 데이터는 숨겨준다.
반환 데이터 설정 ⇒ cat.readOnlyData
이렇게 서비스에서 반환 데이터를 cat이 아닌 cat.readOnlyData를 반환해주면 민감한 데이터를 노출시키지 않고, 프론트에서 필요한 내용만 리턴할 수 있다.
postman 확인
이렇게 반환 데이터를 원하는 데이터만 반환이 잘 되었다.