앞서 공부한 회원가입, 회원 개별 조회, 회원 개별 탈퇴와는 다르게 id가 존재하는지 password가 일치하는지를 확인을 하는 작업을 로그인 핸들링함수에서 작성을 해주셔야 하는데요. 때문에 조회, 탈퇴, 가입과 다르게 코드가 조금 복잡해져서 맨 마지막으로 작업하게 되었습니다.
로그인
왜 회원 조회를 하는데 get이 아닌 post를 사용하나요?
로그인할때 우리가 받아오는 id와 password 값의 노출을 막기 위해 안전한 body에 넣어서 사용하는데요. 보통 body 값은 사용자가 form을 통해서 전송을 했을 때 전달을 받을 수 있습니다. 즉 form을 통해서 전달을 받으면 post를 사용한다는 것을 알 수 있습니다.
app.post("/login", (req, res) => {
const { id, password } = req.body; //입력값
//id가 db에 저장된 회원인지 확인(db와 일치한 데이터가 있는지 "전부" 확인);
let user = "";
db.forEach((v) => {
// forEach 매개변수로 value, key, Map을 순서대로 받아올 수 있다.
if (id === v.id) {
user = v;
}
});
// user가 값이 없거나 undefined => 일치하는 유저가 없다.
if (!user || user == undefined) {
res.status(404).json({
message: "존재하지 않는 유저입니다."
});
return;
}
//일치하는 유저가 존재하지만 그유저의 비밀번호와 일치하지 않을 때
if (user && password !== user.password) {
res.status(404).json({
message: "비밀번호가 틀립니다."
});
return;
}
//user가 존재하고 password가 일치할 때 = 즉 로그인 성공
res.status(200).json({
message: "로그인이 완료되었습니다."
});
});
db에 유저가 일치하는지 forEach를 통해서 value.id값과 id값이 일치하는 데이터를 찾아보았고 이때 일치하면 user에 데이터를 넣도록 만들었습니다. 이를 통해서 유효성 검사를 실행하였는데요. 첫번째로 user가 존재하지 않을 때입니다. user가 빈값 이거나 undefined의 경우에 존재하지 않는 유저라고 메시지를 보내고, return을 사용하여 아래 코드가 읽히지 않게 만들었습니다. 두 번째로 user가 존재하는데 password와 user.password가 같지 않은 경우에 비밀번호가 틀렸다는 메시지를 보내고 return을 보내 아래 코드가 읽히지 않게 하였고, 마지막으로 user가 존재하고 password가 일치할 때 로그인 성공으로 보고 로그인이 완료되었나는 메시지를 보냈습니다.
제가 user의 변수를 선언할때 변숫값으로 '' 빈값을 주었는데요 빈값 대신에 {}를 사용하여 빈객체로 만들 수도 있습니다. 하지만 이 빈 객체에서 console을 찍어보면 {}로 찍히기 때문에 !user(존재하지 않음)나, undefined 같은 값을 받아올 수 없습니다. 그렇다면 객체일 때 user 확인은 어떻게 해야 할까요?
빈객체 user 확인
1. isHasUser와 같은 변수에 Boolean값으로 판단하기
let isHasUser = false // 유저가 존재하지 않는다는 가정
let user = {}
db.forEach((value)=>{
if(req.body.id === value.id){
isHasUser = true;
user = v
}
})
if(isHasUser){
// 유저가 존재함
} else {
// 유저가 존재하지 않음
}
1번은 변수를 따로 만들어 무조건 유저가 존재하지 않다가, forEach를 돌며 일치하는 데이터가 있을 때 true값으로 만들어서 확인을 할 수 있습니다. 이렇게 되면 코드가 한 줄씩 늘어나기 때문에 사용하는데 문제는 없지만 존재할 경우에는 user의 데이터도 따로 값을 담아줘야 한다는 단점이 있습니다.
2. Object.keys()를 활용하여 user 확인하기
let user = {} // Object.keys를 사용하기 위해서는 기본값이 객체여야 합니다.
db.forEach((value)=>{
if(req.body.id === value.id){
user = v
}
})
if(Object.keys(user).length === 0) {
//유저가 존재하지 않음
} else {
//유저가 존재함.
}
2번의 경우에는 1번과 다르게 isHasUser를 사용하지 않고 바로 user만 사용을 하는데요. 빈객체를 확인하는 데 사용된 함수는 바로 Object.keys입니다. 이는 Object의 key값들을 배열로 만들어주는데요, 빈객체라면 object.keys().length가 0인 것을 이용하여 유저의 존재유무를 파악할 수 있습니다.
DB를 이용하여 user 확인하기
기존 Map 객체에서는 boolean 값이나 Object.keys()를 이용하여 user의 존재 여부를 파악했지만 DB를 이용하는 경우에는 select를 이용하여 user를 확인 할 수있습니다.
const [[user]] = await conn.query("select * from users where email = ?;", [email]);
요즘 로그인 시 나오는 문구파악을 통해 코드 수정
'아이디 또는 비밀번호가 틀렸습니다' : 즉 아이디와 비밀번호 둘중에 확실하게 어떤게 틀렸는지 알려주지 않음
if (!user || user.password !== password) {
res.status(404).json({
message: "이메일 또는 비밀번호가 틀렸습니다."
});
return;
}
if의 조건을 두가지를 걸어서 user가 존재하지 않을때 와 password가 user의 password가 일치하지 않을때로 두고 연결을 그리고가 아닌 또는으로 설정하여 둘중 하나라도 조건 성립이 안될 경우 이메일 또는 비밀번호가 틀렸다고 안내메시지 전송을 하였습니다.
1) 이메일이 틀렸을 때
2) 비밀번호가 틀렸을 때
3) 정상 로그인
'프로젝트 > 1.youtube-project' 카테고리의 다른 글
[실전]미니 프로젝트 - 채널 개별 "조회" (0) | 2023.12.14 |
---|---|
[실전]미니 프로젝트 - 채널 "생성" (0) | 2023.12.14 |
[실전]미니 프로젝트 - 회원 개별 "탈퇴" (0) | 2023.12.14 |
[실전]미니 프로젝트 - 회원 개별 "조회" (0) | 2023.12.14 |
[실전]미니 프로젝트 - 회원가입 (0) | 2023.12.14 |