async signUp(createUserDto: CreateUserDto) {
const {email, password, name} = createUserDto;
//해당 이메일의 중복 확인
//사용자 비밀번호 암호화
//사용자 정보 저장
//사용자에게 응답
return await this.usersService.create({email, password, name});
}
우선 회원가입하는 로직은 다음과 같을 것이다.
우선 중복을 확인하고 중복이면 에러를 반환한다.
//해당 이메일의 중복 확인
const existedUser = await this.usersService.findByEmail(email);
if(existedUser){
throw new ConflictException('Email already exists');
}
그 다음은 아래의 코드로 scrypt를 가져와준다.
import {randomBytes, scrypt as _scrypt} from 'crypto';
import {promisify} from 'util';
const scrypt = promisify(_scrypt);
그리고 다음과 같이 salt를 만들어서 암호화하고 이어준다.
//사용자 비밀번호 암호화
//SALT값 생성
//8바이트로 16자리의 16진수 랜덤 문자열을 생성
const salt = randomBytes(8).toString('hex');
//SALT와 합쳐서 암호화
//32자로 암호화된 값을 버퍼로
const hash = (await scrypt(password, salt, 32)) as Buffer;
//암호화된 값(16진수로 변환)과 SALT를 결합
const result = salt + '.' + hash.toString('hex');
전체 메서드는 다음과 같다.
async signUp(createUserDto: CreateUserDto) {
let {email, password, name} = createUserDto;
//해당 이메일의 중복 확인
const existedUser = await this.usersService.findByEmail(email);
if(existedUser){
throw new ConflictException('Email already exists');
}
//사용자 비밀번호 암호화
//SALT값 생성
//8바이트로 16자리의 16진수 랜덤 문자열을 생성
const salt = randomBytes(8).toString('hex');
//SALT와 합쳐서 암호화
//32자로 암호화된 값을 버퍼로
const hash = (await scrypt(password, salt, 32)) as Buffer;
//암호화된 값(16진수로 변환)과 SALT를 결합
const result = salt + '.' + hash.toString('hex');
//사용자 정보 저장
password = result;
//사용자에게 응답
return await this.usersService.create({email, password, name});
}
Http로 테스트를 해보니 다음과같이 정상적인 데이터가 들어간 것을 볼 수 있었다.
저 비밀번호는 암호화가 불가능하다.
그렇기 때문에 비밀번호를 확인하기 위해서 사용자가 전달한 비밀번호를 암호화하고 비교해야 한다.