edit 화면 만듬
.get(getEdit).post(postEdit)
에러1.
로그인하지 않은 사용자가
youtube/user/edit 주소로 들어왔을 때 뜨는 에러
TypeError: /home/uhyun/youtube/src/views/edit-profile.pug:5
3| block content
4| form(method="POST")
> 5| input(placeholder="Username" ,name="username", type="text", required, value=loggedInUser.username)
6| input(placeholder="Name",name="name", type="text", required, value=loggedInUser.name)
7| input(placeholder="Email", name="email", type="email", required, value=loggedInUser.email)
8| input(placeholder="Location", name="location", type="text", required, value=loggedInUser.location)
Cannot read property 'username' of undefined
username이 없다-->
res.locals.loggedInUser = req.session.user이 없어서
res.locals.loggedInUser = req.session.user || {}; or로 empty object추가
--> 로그인하지 않은 사용자가 주소로 들어올 때 안보이는 에러제거함
에러2. 로그인 안한 사용자는 접근 못하게 하기
사용자가 로그인 돼 있지 않은 것을 확인하면 로그인 페이지로 redirect !
로그인 돼 있으면 request 이행 하는 미들웨어
export const protectorMiddleware =(req,res,next)=>{
if(req.session.loggedIn){
next();
}else{
return res.redirect("/login");
}
}
+반대로 로그인 되어 있지 않은 사용자만 접근 할 수있는 middleware
로그인했는데 다시 로그인 페이지로 가면 안되잖아
export const publicOnlyMiddleware = (req,res,next)=>{
if(!req.session.loggedIn){
return next();
}else{
return res.redirect("/");
}
}
적용
userRouter
userRouter.get("/logout", protectorMiddleware, logout);
로그인 되어 있는 유저만 로그아웃 할 수있게
userRouter.route("/edit").all(protectorMiddleware).get(getEdit).post(postEdit);
로그인 되어있는 유저만 편집 할 수있게
userRouter.get("/github/start", publicOnlyMiddleware, startGithubLogin);
userRouter.get("/github/finish", publicOnlyMiddleware, finishGithubLogin);
퍼블릭, 로그인되어있지 않는 사람만 로그인 할 수있게
+팁 파일이 열려있고 열어 놓은 파일의 함수를 작성하면 vsc가 import를 도와줌
export const postEdit= async (req, res)=>{
const{
session: {
user: { _id }, // const id = sesssion.user.id 와 같음 아래와 혼용하여 쓸 수있어서 씀
},
body: { name, email, username, location}, //const {name,email,user,name,location} = req.body와같음
}=req;
await User.findByIdAndUpdate(_id,{ //몽고db에서 user를 id로 찾아서 업데이트
name, //form name="name" : req.body.name="name"
email, //email:email
username,
location,
});
return res.render("edit-profile");
}
Error 1.처음에 _id가 아닌 id라고 적었을 때 작동하지 않았음
localsMiddleware에 console.log(req.session.user)하면
user 객체에 id가아닌 _id로 표기 되어있어서
user object에 없는 id속성을 가져 올 수 없는 것
Error 2. mongodb에서만 바뀌고 페이지에는 바뀌지 않음
template 파일안 form을 보면
input(placeholder="Username" ,name="username", type="text", required, value=loggedInUser.username)
값이 loggedinUser.username인데 localsMiddleware에서 생성되고
res.locals.loggedInUser = req.session.user || {};
req.session.user는 로그인할 때 한 번 생성됨 // req.session.user = user;
그래서 user는 업데이트되어있지만 session은 업데이트 되어있지 않은 것
session과 db는 연결 되어있지 않음
await User.findByIdAndUpdate(_id,{ //몽고db에서 user를 id로 찾아서 업데이트
name, //form name="name" : req.body.name="name"
email, //email:email
username,
location,
});를
방법 1 직접 업데이트하기
await User.findByIdAndUpdate(_id,{
name,
email,
username,
location,
});
req.session.user={
...req.session.user //req.session.user에 있는 모든 내용으로 덮어쓰고
name, //이것들만 바꾸기
email,
username,
location,
});를
방법 2
const updatedUser= await User.findByIdAndUpdate( _id,
{
name,
email,
username,
location,
},
{ new: true } //option
);
req.session.user = updatedUser;
return res.render("edit-profile");
}
기본적으로 findByIdAndUpdated는 업데이트되기 전의 데이터를 return 해준다
옵션으로 new:true를 설정해주면 업데이트가 된 데이터를 return해준다.
그전 데이터는 필요없고 가장 최근에 데이트를 요구
Error3. 이메일, 유저네임 변경 시 이미 존재하는 것인지 체크
export const postEdit= async (req, res)=>{
const{
session: {
user: { _id },
},
body: { name, email, username, location},
}=req;
const existUsername = await User.findOne({username});
const existEmail = await User.findOne({email});
if(
(existUsername !== null && existUsername._id != _id) ||
(existEmail !== null && existEmail._id != _id)
){
return res.render("edit-profile",{pageTtile: "Edit Profile", errorMessage:"usernae/email is already taken"})
}
const updatedUser= await User.findByIdAndUpdate(
_id,
{
name,
email,
username,
location,
},
{ new: true }
);
req.session.user = updatedUser;
return res.redirect("/users/edit");
}