- 마이 페이지 구성
- 찜 목록 (룰렛, 찜 정보) (Mypage.js)
- 닉네임 변경 (ChangeNickname.js)
- 비밀번호 변경 (ChangePassword.js)
- 회원 탈퇴 (Resign.js)
마지막 네 번째 메뉴에 존재하는 회원탈퇴입니다.
회원탈퇴 UI
삭제하기 위해 비밀번호를 확인하는 Input과 체크박스 그리고 탈퇴하기 버튼으로 이루어져있습니다.
const ID = sessionStorage.getItem("ID");
const [PW, setPW] = useState("");
const [checked, setChecked] = useState(false);
앞서 닉네임 변경과 마찬가지로 변수와 state구조가 동일합니다.
ID는 sessionStorage를 통해 로그인 시 저장한 ID이고
PW는 Input에 입력한 비밀번호로 login 데이터베이스에 저장돼있는 비밀번호와 동일한지 검사를 해주는 역할을 합니다.
마지막으로 checked는 체크박스의 상태를 관리해주며 추후 체크박스의 체크가 되어있지 않다면 탈퇴하기 버튼이 눌리지 않게 합니다.
<div className=" border bg-light p-3 container col-8 m-2 rounded col rounded mx-auto ">
<h3 className="pt-2">회원 탈퇴</h3>
<form onSubmit={submitHandler}>
<label className="p-3 font-500">현재 비밀번호</label>
<input type="password" className="form-control form-control-lg mb-3 rounded-pill" placeholder="계정을 삭제하려면 현재 사용중인 비밀번호를 입력하세요" value={PW} onChange={PWHandler}></input>
<label className="p-3 font-500">계정삭제시 모든 게시물이 삭제되며 복구 불가능합니다.</label>
<div className="form-check">
<input class="form-check-input" type="checkbox" value="" checked={checked} onChange={handleChange} id="flexCheckDefault"></input>
<label className="form-check-label" for="flexCheckDefault">
동의합니다.
</label>
</div>
<div className="d-grid gap-2 col-md-11 mx-auto">
<button onSubmit={submitHandler} className="btn btn-lg press_btn mt-5 gap-2 " type="submit" disabled={!checked}>
탈 퇴 하 기
</button>
</div>
</form>
</div>
const handleChange = () => {
setChecked(!checked);
};
체크박스의 체크여부에 따라 checked의 boolean 값을 설정하여 줍니다.
[클라이언트]
// 회원 탈퇴
async function submitHandler(e) {
e.preventDefault();
let saltPw;
try {
await axios.get("api/pw").then((응답) => {
for (let i = 0; i < 응답.data.length; i++) {
// 암호화된 비밀번호를 변수에 저장
if (응답.data[i].아이디 === ID) {
saltPw = 응답.data[i].패스워드;
}
}
let body = {
id: ID, // 현재 로그인된 아이디 정보 가져와야함
current: PW,
hash: saltPw,
};
axios.post("resign", body).then((res) => {
if (res.data === "현재 패스워드 안맞음") {
alert("패스워드를 잘못 입력하셨습니다.");
} else {
//DB에서 회원정보 지우기
//로그인 정보 날리기
alert("회원탈퇴가 완료되었습니다.");
sessionStorage.clear();
navigate("/");
location.reload();
}
});
});
} catch (err) {
console.log(err);
}
}
[서버]
//회원탈퇴
app.post("/resign", function (req, res) {
db.collection("login").findOne({ 아이디: req.body.id }, function (err, result) {
if (result) {
bcrypt.compare(req.body.current, req.body.hash).then((result) => {
if (result) {
//패스워드 일치
db.collection("login").deleteOne({ 아이디: req.body.id }, function (err, result) {
// console.log("삭제완료");
res.redirect("/");
});
} else {
//패스워드 일치하지 않음
res.json("현재 패스워드 안맞음");
}
});
} else {
// 입력한 패스워드가 맞을 때 최종적으로 selection에 있는 찜목록들을 삭제함
db.collection("selection").deleteMany({ id: req.body.id });
}
});
});
닉네임 변경하기와 마찬가지로 탈퇴하기를 눌렀을 때
login DB의 존재하는 정보들을 가지고와 현재 로그인 되어있는 나의 ID를 통해
암호화된 비밀번호를 가지고옵니다. 그 후, saltPw에 대입을 해줍니다.
body에 현재 id, 입력한 비밀번호, 암호화된 비밀번호 세 가지를 담아 서버로 보냅니다.
여기서의 서버에 역할은
우리가 입력한 id를 findOne으로 찾아 암호화된 비밀번호를 복호화 하여 비교합니다.
여기서 우리가 입력한 비밀번호와 같지 않다면 "현재 패스워드 안맞음"을 client로 전송하여 그에 해당하는 알림창을 띄우고
패스워드가 일치한다면 login 데이터베이스에 존재하는 해당 id를 찾아 deleteOne을 해주며 삭제하고 그와 동시에 selection에 나의 ID에 해당했던 찜목록들을 deletemany를 통해 모두 삭제하여줍니다,
이는 성공적으로 회원탈퇴를 의미하므로 client에게 알림창을 띄우며 로그인창으로 이동시켜줍니다.
여기서 앞서 언급한대로 체크박스를 누를 때마다 checked 변수의 boolean값이 변경되며 boolean값이 false일 땐 버튼 자체가 비활성화 되기 때문에 탈퇴하기 버튼을 누를 수 없습니다.