개발일지
[NestJS] 로그아웃 및 비밀번호 재설정 본문
로그아웃
플로우
제가 생각한 로그아웃 플로우는 다음과 같습니다.
- 클라이언트에서 로그아웃 api를 요청합니다.
- DB에 저장된 refresh token을 삭제한 후 결과를 response 합니다.
- 삭제 성공일 경우, 헤더에 있는 access token을 제거합니다.
구현
// auth/auth.controller.ts
@Delete('sign-out')
async signOut() {
const userId = 1;
const data: SignOutUserDto = {
userId,
};
return await this.authService.signOut(data);
}
// auth/auth.service.ts
async signOut(data: SignOutUserDto) {
return await this.usersRepository.deleteRefreshToken(data.userId);
}
// auth/auth.repository.ts
async deleteRefreshToken(userId: number) {
await this.prisma.refreshTokens.delete({
where: {
userId,
},
});
}
비밀번호 재설정
유틸리티 타입 PickType, Omit
을 사용하여 dto를 정의했습니다.
// auth/auth.controller.ts
@Patch('reset/password')
async resetPassword(@Body() body: Omit<ResetPasswordDto, 'userId'>) {
const userId = 1;
const data: ResetPasswordDto = {
...body,
userId,
};
return await this.authService.resetPassword(data);
}
export class ResetPasswordDto extends PickType(SignUpUserDto, [
'password',
'checkPassword',
]) {
userId: number;
}
디스트럭쳐링하여 객체 값들을 변수로 저장했습니다. { password: currPassword }
는 변수명 password를 currPassword로 재정의합니다. 변경하려는 비밀번호가 현재 비밀번호와 동일하거나 password와 checkPassword가 일치하지 않으면 에러를 던집니다.
async resetPassword(data: ResetPasswordDto) {
const { userId, password, checkPassword } = data;
const { password: currPassword } =
await this.usersRepository.findUserByWhereOption({
id: userId,
});
if (await bcrypt.compare(password, currPassword)) {
throw new CustomException(UsersException.SAME_CURR_PASSWORD);
}
await this._validatePassword(password, checkPassword);
return await this.usersRepository.updatePassword(userId, password);
}
변경하려는 비밀번호를 암호화하여 업데이트합니다.
// users/users.repository.ts
async updatePassword(userId: number, password: string) {
return await this.prisma.users.update({
where: {
id: userId,
},
data: {
password: await bcrypt.hash(password, 10),
},
});
}
ValidatePasswordType 변경
ValidatePasswordType
을 'signUp' | 'signIn'
처럼 서비스 단위로 정의하니 다른 서비스에서 사용될 때마다 타입을 추가해줘야하는 번거로움이 생깁니다.
이를 '암호화 된 데이터와 비교할 경우', '암호화되지 않은 데이터와 비교할 경우'의 기준으로 변경했습니다.
// 변경 전
type ValidatePasswordType = 'signUp' | 'signIn';
// 변경 후
type ValidatePasswordType = 'clearPassword' | 'hashedPassword';
private async _validatePassword(
password: string,
checkPassword: string,
type: ValidatePasswordType = 'clearPassword',
) {
if (type == 'clearPassword' && password !== checkPassword) {...}
if (type == 'hashedPassword' && !(await bcrypt.compare(password, checkPassword))
) { ...}
'NestJS, Node.js > #01 Project - 투표 커뮤니티' 카테고리의 다른 글
[NestJS] Prisma 환경 변수 문제 해결하기 (0) | 2022.11.16 |
---|---|
[NestJS] 환경변수 설정하기 - config, cross-env, joi (0) | 2022.11.16 |
[NestJS] 마이페이지 - 프로필, 작성한 투표글, 댓글 조회 (0) | 2022.11.09 |
[NestJS] 댓글 조회, 수정, 삭제 구현 (0) | 2022.11.09 |
[NestJS] 댓글 좋아요 및 취소 (0) | 2022.11.09 |