- 마이 페이지 구성
- 찜 목록 (룰렛, 찜 정보) (Mypage.js)
- 닉네임 변경 (ChangeNickname.js)
- 비밀번호 변경 (ChangePassword.js)
- 회원 탈퇴 (Resign.js)
세 번째 메뉴 비밀번호 변경입니다.
비밀번호 변경 UI
const ID = sessionStorage.getItem("ID");
const [currentPW, setcurrentPW] = useState("");
const [newPW, setnewPW] = useState("");
const [renewPW, setrenewPW] = useState("");
먼저 변수와 state의 구조입니다.
ID에 sessionStorage에서 꺼내온 로그인시의 ID값이 들어가 있고
현재 비밀번호를 관리할 currentPW, 새로운 비밀번호를 입력할 newPW, 새로운 비밀번호의 일치값을 확인하는 renewPW 변수 state들로 이루어져 있습니다.
<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={currentPW} onChange={cPWHandler}></input>
<label className="p-3 font-500">비밀번호 변경하기</label>
<input type="password" className="form-control form-control-lg rounded-pill" placeholder="새 비밀번호를 입력하세요" value={newPW} onChange={nPWHandler}></input>
<input type="password" className="form-control form-control-lg mt-3 rounded-pill" placeholder="새 비밀번호를 다시 입력하세요" value={renewPW} onChange={rPWHandler} />
<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">
변경사항 저장
</button>
</div>
</form>
</div>
세 가지의 onChange 함수 모두 state을 활용하여 입력값을 동적으로 인식하며 변동시켜 줍니다.
물론 세 가지의 value는 각각의 state에 해당하는 변수값이 들어가, 우리가 동적으로 바꾸어준 변수의 값이 최종적으로 전달되게 됩니다.
[클라이언트]
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: currentPW,
hash: saltPw,
new: newPW,
re: renewPW,
};
axios.post("changePW", body).then((res) => {
if (res.data === "현재 패스워드 안맞음") {
alert("현재 패스워드를 잘못 입력하셨습니다.");
} else if (res.data === "비밀번호 재입력 오류") {
alert("새 비밀번호가 맞지 않습니다.");
} else if (res.data === "비밀번호 동일") {
alert("기존 비밀번호와 새로운 비밀번호가 동일합니다.");
} else {
navigate("/Main");
alert("비밀번호 변경이 완료되었습니다.");
}
});
});
} catch (err) {
console.log(err);
}
}
[서버]
[/api/pw]
// 데이터베이스 암호화 비밀번호 전달 API
app.get("/api/pw", function (요청, 응답) {
db.collection("login")
.find()
.toArray(function (에러, 결과) {
응답.json(결과);
});
});
[/changePW]
//비밀번호 변경 API
app.post("/changePW", 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) {
//새 비밀번호와 다시 입력한게 다를때
if (req.body.new != req.body.re) {
res.json("비밀번호 재입력 오류");
} else {
//현재 비밀번호와 새로 작성한 비밀번호가 동일할때
if (req.body.new == req.body.current) {
res.json("비밀번호 동일");
} else {
//정상적으로 바꾸면 DB 업데이트 하고 홈 이동
bcrypt.hash(req.body.new, saltRounds, (err, hash) => {
db.collection("login").updateOne({ 아이디: req.body.id }, { $set: { 패스워드: hash } }, function (err, result) {
res.redirect("/Main");
});
});
}
}
}
else {
//패스워드 일치하지 않음
res.json("현재 패스워드 안맞음");
}
});
}
});
});
먼저 변경사항 저장 버튼을 누르는 순간 submitHandler를 통해 api/pw에서 login 데이터베이스에 담긴 정보들을 가져다 줍니다.
(*이 부분은 post로 해결하면 조금 더 가벼운 코드가 되었을텐데라는 아쉬운 생각을 갖습니다.)
그 후 client로 가져온 login의 정보들 중에 session에 저장되어 있는 나의 ID와 동일한 ID를 찾았다면 saltPW에 login 데이터베이스에 존재하는 암호화 패스워드를 saltPw 변수에 저장하여 줍ㄴ디ㅏ.
그 후 body에 보낼 데이터들을 짜줍니다.
- id : ID
- current : 우리가 입력한 현재 비밀번호
- hash : 암호화된 비밀번호
- new : 새로 바꿀 비밀번호
- re : 비밀번호 확인 비밀번호
그 후에 changePW에 post 요청을 보내 나온 결과에 따라 알림창을 띄우거나 성공적으로 변경한 경우는 Main페이지로 이동을 시키며 알림창을 띄워줍니다.
이때 서버에서 하는 역할은
우리가 로그인시 저장했던 세션존재 ID를 전달해줌으로 login 데이터베이스에서 해당 ID에 해당하는 비밀번호를 findOne을 해줍니다.
그렇게 해서 찾은 비밀번호를 bcrypt를 통해 복호화하면서 만약 일치할시 "비밀번호 동일"을 통해 성공적으로 비밀번호를 다시 bcrypt.hash을 통해 다시 hash + salt를 해준 후 updateOne을 통해 데이터베이스에 존재하는 비밀번호를 다시 바꾸어줍니다. 그 후 redirect를 통해 Main으로 보내줍니다.
여기서 여러가지 경우의 수에 대비하여
현재 비밀번호가 일치하지 않을 때 : 현재 패스워드 안맞음
new와 re가 같지 않을 때 : 비밀번호 재입력
new와 current가 같을 때 : 비밀번호 동일
을 결과로 보내주어 client에서 처리하도록 했습니다.
서버로부터 "현재 패스워드 안맞음"이라는 응답을 받고 현재 비밀번호와 입력한 비밀번호가 일치하지 않는다면 알림창을 띄워줍니다.
서버로부터 "비밀번호 재입력"이라는 응답을 받고 응답이 우리가 지정한 값과 똑같다면 새 비밀번호가 맞지 않다는 알림창을 띄워줍니다.
서버로부터 "비밀번호 동일"이라는 응답을 받고 우리가 동일한 비밀번호로 변경을 시도 했을 때 기존 비밀번호와 새로운 비밀번호가 같다는 알림창을 띄워줍니다.