#6 회원탈퇴 기능 개발

seojin's 개발블로그·2023년 8월 6일
2

영화 사이트 제작

목록 보기
6/19

이번에 만든 기능은 회원탈퇴 기능 + 회원 데이터 백업 기능이다.
데이터 백업의 경우 관리자의 실수로 인한 삭제 및 혹여나 회원정보가 필요할 경우를 대비해 데이터를 보관한다는 가정을 하여 구현했다.

📌 회원 탈퇴 Api

1. 시퀀스 다이어그램


회원 데이터의 id로 삭제 요청을 하고 데이터베이스에서는 회원정보를 백업후
삭제 요청이 들어온 데이터를 삭제 한다는 알고리즘을 생각했다.

2. API 명세


반환 데이터는 없고 회원탈퇴의 성공여부만 전달한다는 생각으로 명세를 작성했다.

3. 구현

I. Controller

@DeleteMapping("/api/member/withdrawMember/{memberId}")
public ResponseEntity<ApiResponse<Map<String, Object>>> withdrawMember(@PathVariable Long memberId){
    try {
        memberService.deleteMember(memberId);
        return ResponseEntity.ok().body(new ApiResponse<>(1, "회원탈퇴 성공", null));
    } catch (RuntimeException ex){
        return ResponseEntity.ok().body(new ApiResponse<>(0, "회원탈퇴 실패", null));
    }
}

회원탈퇴 성공시와 실패시의 메세지 반환이 다르게 설정해줬다.
실패의 경우 회원탈퇴시에는 로그인이 되어있고 로그인된 id값을 반환한다는 가정을 하기 때문에 여러 예외를 포괄하도록 런타임 예외로 설정해줬다.
예외처리에 대해 더 공부하고 좀 더 세분화할 예정

반환 타입은 다른 api들과 마찬가지로 ApiResponse 타입을 만들어 이용하였다.

II. Service

public void deleteMember(Long id) {
    try {
        memberRepository.deleteById(id);
    }  catch (Exception ex) {
        throw new RuntimeException();
    }
}

jpa에서 delete~~()의 반환타입이 void라서 orElseThrow를 사용하지 못해서 try catch로 에러 반환을 해주도록 구현했다.

4. 테스트


기존의 데이터 총 4명의 유저가 있다.

I. 실패 테스트

현재 없는 6번을 넣었을때 정상적으로 탈퇴 실패가 나오는것을 확인했다.

II. 성공 테스트

데이터에 있는 4번유저 탈퇴 테스트를 해보았다. 탈퇴 성공 메세지가 출력되고


데이터베이스에서도 4번 유저가 정상적으로 삭제된 것을 확인했다.

📌 회원 데이터 백업 설정

회원 탈퇴시 데이터를 자동으로 백업하기 위해 데이터베이스에 트리거를 만들어 주었다.

1. 백업 테이블

CREATE TABLE members_backup (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    phone_number VARCHAR(20) NOT NULL,
    role_type VARCHAR(50) NOT NULL,
    sex VARCHAR(10) NOT NULL,
    birthday DATE NOT NULL,
    signup_at DATETIME ,
    updated_at DATETIME, 
    withdraw_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

기존의 테이블에 추가적으로 탈퇴일 애트리뷰트를 추가해주었다.
default값으로 탈퇴시의 시간을 기록하게 설정했다

2. 트리거

DELIMITER //
CREATE TRIGGER backup_members BEFORE DELETE
ON members FOR EACH ROW 
BEGIN
	INSERT INTO members_backup (email, password, phone_number, role_type, sex, birthday, signup_at, updated_at) 
	VALUES (OLD.email, OLD.password, OLD.phone_number, OLD.role_type, OLD.sex, OLD.birthday, OLD.signup_at, OLD.updated_at);
END;
//
DELIMITER ;

삭제 작업전에 작동하도록 만들었으며 백업 테이블에 기존 데이터의 id를 제외한 값들을 기록한다.
DELIMITER는 BEGIN~END사이에 있는 세미콜론이 트리거의 종료로 인식되는것을 방지하는 기능을 한다.
//로 구분자를 지정하고 뒤에서 다시 ;로 구분자를 바꿔준다.

3. 테스트

DELETE FROM members where member_id = 3;

3번 유저를 삭제하는 명령

SELECT * FROM members;

유저 테이블을 조회

본 테이블에서 3번 유저가 삭제된 것을 확인

SELECT * FROM members_backup

백업 테이블을 조회

백업테이블에 정상적으로 데이터가 백업되었다.
삭제 날짜도 등록이 되었다.

📌 발생했던 문제들

1. 가입일, 수정일 타입 문제


원본 테이블의 가입일, 초단위까지 기록이 되고있다.

백업 테이블의 가입일, 날짜까지만 기록이 되고있다.
원인은 당연하게도 내가 테이블을 잘못 만들었기 때문이였다.

CREATE TABLE members_backup (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    phone_number VARCHAR(20) NOT NULL,
    role_type VARCHAR(50) NOT NULL,
    sex VARCHAR(10) NOT NULL,
    birthday DATE NOT NULL,
    signup_at DATE ,
    updated_at DATE, 
    withdraw_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

가입일과 수정일을 DATETIME이 아닌 DATE로 설정해서 생긴 문제였다.
drop 테이블을 하고 테이블을 다시 만들까 했지만
이런 문제가 발생했을때 백업 테이블을 지우는건 당연히 안될거라고 생각이 들어서 기존 테이블을 수정하는 방식으로 해결을 하기로 했다.

ALTER TABLE members ALTER COLUMN signup_at DATETIME;

데이터 타입을 수정하는 구문을 실행해주었는데

위와 같은 에러가 발생했다.
구문오류인데 문법에는 오류가 없는것으로 생각해 데이터 타입 변경시 생기는 오류상황을 찾아보았는데 타입 변경시 오류 대처 여기 작성된 내용을 보니(이용한 db는 다르다)
데이터 타입이 호환이 안되는 경우 생기는 문제인 것 같다.
날짜 - 날짜, 시간이라 변경이 가능할 줄 알았는데 호환이 안되나보다

그래서 temp 애트리뷰트를 만들어 데이터를 수정하고 복사해주기로 했다.
과정은
temp 애트리뷰트 생성 -> 기존 애트리뷰트 복사 -> 기존 애트리뷰트 삭제
-> temp 이름을 변경
과정으로 해결을 하기로 했다.

I. temp 애트리뷰트 생성

ALTER TABLE members_backup
ADD COLUMN signup_at_temp DATETIME,
ADD COLUMN updated_at_temp DATETIME;

II. 기존 애트리뷰트 복사

UPDATE members_backup
SET signup_at_temp = STR_TO_DATE(signup_at, '%Y-%m-%d'),
    updated_at_temp = STR_TO_DATE(updated_at, '%Y-%m-%d');

STR_TO_DATE
update문 사용법을 찾다가 발견한 함수 데이터를 날짜로 변경해주는 함수이다.
현재 백업 테이블은 날짜까지만 저장이 되어있어서 함수의 데이터도 날짜까지만 설정을 해주었다.
temp 애트리뷰트로 복사된 데이터

III. 기존 애트리뷰트 삭제

ALTER TABLE members_backup
DROP COLUMN signup_at,
DROP COLUMN updated_at;


기존 가입일, 수정일 애트리뷰트를 삭제해주었다.

IV. temp 애트리뷰트 이름변경

ALTER TABLE members_backup
CHANGE COLUMN signup_at_temp signup_at DATETIME,
CHANGE COLUMN updated_at_temp updated_at DATETIME;


temp의 이름을 바꾸어주면서 마무리를 했다.

V. 테스트

DELETE FROM members where member_id = 2;

2번 회원을 삭제하는 구문

이제 정상적으로 기존 회원의 가입, 수정일이 초단위까지 백업이 된다.

2. 데이터베이스 시간대 설정

데이터 삭제당시의 시간은 21시 였는데 12시로 기록이 되어있었다.
RDS의 지역이 해외라서 발생하는 문제인듯하다.

select NOW();

데이터베이스의 시간을 확인해보았다.

당시의 시간은 21시경이었다.
찾아보니 AWS RDS는 UTC (협정 세계시) 시간대를 이용한다고 한다
그래서 RDS의 시간대를 변경하는 방법을 찾아보았다.

I. AWS RDS 설정 변경

RDS TIMEZONE 변경
위 블로그를 참고하였다

rds의 파라미터 그룹으로 들어가서 그룹 생성후


데이터베이스의 버전과 이름을 설정한 후
파라미터 그룹 수정으로 들어가서 time_zone을 검색하면 된다
그리고 enter parameter value에 Asia/Seoul을 입력해주면 파라미터 그룹 설정은 끝

그 다음엔 이용하는 DB로 이동해서

추가 구성에서 파라미터 그룹을 변경후

즉시 적용후 인스턴스 수정 버튼을 눌러주면 된다.

혹시 적용이 안된다면 아래와 같이 재부팅을 해주면 적용이 된다.

II. 테스트

DELETE FROM members where member_id = 1;

1번 회원을 다시 삭제해 보았다

확인을 해보니 이전 삭제 데이터들의 삭제 시간도 +9시간씩 올바르게 수정이 되어 있었다.
시간대를 변경시 기존 데이터중 현재 설정과 다른 시간대를 기준으로 작성된 데이터들은 자동으로 수정이 되는것 같다. 편리하다

📌 후기

해결할 문제들이 계속 나왔지만 스무스하게 진행이 되었고
이미지가 많아 글이 길어보이지만 시간도 얼마 걸리지 않았다.
RDS 설정등 계속 새로운걸하니까 재미도 좀 있는것 같다 ㅋㅋ
어서 나머지 기능들을 만들고 시큐리티 파트로 넘어가고싶다
이번주는 진짜 속도를 내서 진행하고 팀원분과 각자 만든 부분들도 어서 병합을 해봐야겠다 이번주도 조금..? 성장한것 같아 기분이 좋게 마무리

profile
개발 공부하는 블로그

0개의 댓글