middleware를 videoController에 추가 해본다.
그래서 videoRouter
의 /edit
,/delete
, /upload
를 보호 할거다.
로그인 돼 있어야만 접근할수 있게 만든다.
이렇게 하는 이유는 나중에 video model
과 user mogel
을 연결하기 때문이다.
지금은 model
들이 나눠져 있다. 현재 video
는 아직 user
랑 아무 접점이 없다.
나중에 video
가 어떤 user
에 의해 업로드 되는지 알아 보겠다.
video
의 소유자를 설정하는 거다.
소유자를 설정하면 videoController
에서 몇가지를 수정해야 한다.
예를 들어 소유자가 아니면 video
를 수정할 수 없게 하거나 삭제 할수 없게 하는거다.
video
에 소유자를 설정하기 위해 웹사이트에 계정이 있고, 로그인돼 있는 사람만
video
를 업ㄹ로드 할수 있게 한다.
그래서 route
( /edit
,/delete
, /upload
)를 보호 할거다.
videoRouter.get("/:id([0-9a-f]{24})", watch);
videoRouter.route("/:id([0-9a-f]{24})/edit").get(getEdit).post(postEdit);
videoRouter.route("/:id([0-9a-f]{24})/delete").get(deleteVideo);
videoRouter.route("/upload").get(getUpload).post(postUpload);
모두 get
,post
를 포함하고 있다. 그래서 all()
을 써주면 된다.
videoRouter.get("/:id([0-9a-f]{24})", watch);
videoRouter
.route("/:id([0-9a-f]{24})/edit")
.all(protectorMiddleware)
.get(getEdit)
.post(postEdit);
videoRouter
.route("/:id([0-9a-f]{24})/delete")
.all(protectorMiddleware)
.get(deleteVideo);
videoRouter
.route("/upload")
.all(protectorMiddleware)
.get(getUpload)
.post(postUpload);
그리고 prtectorMiddleware
를 import
를 해줘야 한다.
파일이 열려있고 열어 놓은 파일의 함수를 작성하면
VSC
가import
를 도와 준다.
videoRouter
의 /edit
이 보호 되있고, /delete
도 보호 돼있고, /upload
도 보호 된다.
이제
Edit Profile
을 만들어 준다.
그리고 Upload Video
는 로그인 된 사람들만 볼수 있는거니까 바꿔줘야 한다.
base.pug
에서
if loggedIn
li
a(href="/videos/upload") Upload Video
Upload Video
를 loggedIn
안으로 옮겨 준다.
edit-profile.pug
를 보면
extends base
block content
form(method="POST")
input(placeholder="Name",name="name", type="text", requeired, value=loggedInUser.name)
input(placeholder="Email",name="email", type="email", requeired, value=loggedInUser.email)
input(placeholder="Username",name="username", type="text", requeired, value=loggedInUser.username)
input(placeholder="Location",name="location", type="text", requeired, value=loggedInUser.location)
input(type="submit", value="Update Profile")
모두 name
을 가지고 있다. user
가 post request
를 보내면 body
를 받을수 있다.
userController.js
에서
export const postEdit = (req, res) => {
const {} = req.body;
form
으로 부터 받는걸 알고 있다. 다음으로 body
로부터 모든걸 받아서 넣어주는거다.
const { name, email, username, location } = req.body;
그 다음 mongo
를 사용해 주면 된다. user
를 찾아서 업데이트 해줘야 한다.
user model
이 있는걸 확인하고 async
를 추가해 준다.
export const postEdit = async (req, res) => {
const {
session: {
user: { id },
},
body: { name, email, username, location },
} = req;
await User.findByIdAndUpdate(id, {
name,
email,
username,
location,
});
return res.render("edit-profile");
};
그리고 await User.
를 쓴다. User.
으로 할수 있는게 많다.
예를 들면 findById
도 있고 현재는 findByIdAndUpdate
를 사용한다.
먼저 업데이트하려는 id
를 보내줘야 한다. 현재 로그인된 user
의 id
를 얻기 위해서
request object
를 사용 해야 한다.
request object
의 req.session.user
가 있다.
user object
를session
에 있다는걸 기억하자.
그래서 req.session
에 있는 user object
에서 id
를 찾을수 있다.
좀더 보기 좋게 하기 위해서 session
안에서 user
를 찾고 id
를 꺼내올수 있다.
const id = req.session.user.id
와 같은 거다.
이 방법이 좋은 이유는 혼합하기 좋기 때문이다.
예를 들어 이 방법을 사용하면 session
안에 있는 user
의 id
를 찾을수 있다.
req.body
안에 있는 name
,email
,username
,location
정보도 가져 올수 있다.
그래서 const id = req.session.user.id
와 const { name, email, username, location } = req.body;
를 없애 줄수 있다.
훨씬 보기 좋다. 이게 바로 ES6
이다.
req
안에 있는 session
에서 user
의 id
를 얻었다.
또 req
안에 body
에 있는 name
,email
,username
,location
을 얻었다.
그리고 User.findByIdAndUpdate()
에다가 req.session.user
안에 있는 id
를 넣어 준다.
업데이트 하기 위해서 name
,email
,username
,location
을 넣어준다.
이 변수들은
form
에서 온다는걸 기억한다.
input
에 name
을 입력해 주지 않으면 안된다.
form
으로부터 name
,email
,username
,location
을 받았다.
이 정보는 req.body
에서 찾을 수 있다. 그리고 로그인된 user
의 정보를 업데이트 하고 싶다.
보다시피 user
가 누구냐고 묻지 않는다. url
로 부터 id
를 받고 있는게 아니다.
user id
를 가지고 있는 session
에서 받는거다.
그래서 findByIdAndUpdate
함수를 쓸때 첫번째 argument
는 id
이다.
두번째는 UdateQuery
이고 callback
을 사용 할수도 있지만 await
를 사용 할수도 있다.
한번 테스트를 해보겠다. 새로고침하고 email
을 바꿔본다.
업데이트가 되지 않았다. 왜 그런지 알아 본다. 아마 user
가 id
를 가지고 있지 않을수도 있다.
middleware
에서 로그인 된 유저를 console.log
해서 확인해 본다.
res.locals.loggedInUser = req.session.user || {};
console.log(req.session.user);
새로고침하고 email
을 수정 시도를 다시 해보고 콘솔을 확인해 보면
id
가 아닌 _id
의 정보를 받고 있다. 그러면 이제 _id
로 바꿔 주면 작동 할거다.
export const postEdit = async (req, res) => {
const {
session: {
user: { _id },
},
body: { name, email, username, location },
} = req;
await User.findByIdAndUpdate(_id, {
그래도 업데이트 되지 않고 있다. 콘솔에 아무 에러가 없는거 보니 코드가 작동하는건 확실하다.
이번에는 DB
를 확인해 본다. DB
를 확인해 보니 수정을 요청 한 게 저장이 되어있다.
DB
에서 email
이 업데이트 되긴 했다. 문제는 페이지에서 새로고침을 해도 바뀌지 않는다는 거다.
홈페이지에서는 계속 이전 이메일이 나온다. DB
에는 새로운 이메일인데 말이다.
생각해보면 edit-profile
에서 loggedInUser
의 값을 입력했다.
그러면 loggedInUser
가 언제 생성 된건지 생각해본다.
loggedInUser
는 localsMiddleware
에서 생성되었다.
middleware.js
에서
export const localsMiddleware = (req, res, next) => {
여기서 loggedInUser
를 req.session.user
이라고 정의 하고 있다.
그러면 req.session.user
는 어디서 생성 되는지 알아본다.
바로 로그인 할때이다. 로그인 하는곳으로 가 본다.
userController.js
에서
req.session.loggedIn = true;
req.session.user = user;
여기서 로그인할때 user
를 req.session.user
에 입력해 준다.
그래서 user
는 업데이트 했는데 session
이 업데이트 되지 않는다.
DB
에서는 user
를 업데이트했는데 session
은 DB
와 연결 돼 있지 않다.
session
에 user object
를 넣었는데 user object
를 업데이트 했다면
session
도 업데이트 해줘야 한다.