노마드 코더/유튜브 클론

[JavaScript, Node.js] 유튜브 클론 정리 8장 (2) - 유저 아바타, 파일 업로드(Multer)

LooanCheong 2023. 6. 29. 14:05
반응형

머리글

이번 시간에는 유저의 아바타 기능을 위해 파일 업로드 하는 방법을 알아보자.

파일 업로드

우선 업로드를 위해선 업로드할 공간을 만들어줘야 한다.

프로필 수정 페이지를 변경해 주자.

    form(method="POST", enctype="multipart/form-data")
        label(for="avatar") Avatar
        input(type="file", id="avatar", name="avatar", accept="image/*")
        ...

label과 아바타 파일을 업로드하기 위한 input을 만들어주었다.
그리고 이미지 형식만 선택할 수 있게 accept 항목을 정해주었다.

그리고 미들웨어를 사용해야 하는데 이를 설치해 보자.

npm i multer

Multer는 파일을 업로드할 수 있게 해 준다.

Multer를 사용하기 위해선 우리의 form을 multipart form으로 만들어야 한다.
그래서 form의 enctype에 설정을 해주었다.
이는 우리의 form이 다르게 encode 된다는 것을 의미한다.

그리고 middleware를 만들어서 설정해줘야 한다.

export const uploadFiles = multer({ dest: "uploads/" });

설정을 해야 할 목록은 dest부분인데 이는 유저가 파일을 올리면 어디에 저장할지 정하는 것이다.
기본적으로 파일 자체를 저장하는 것보다는 파일은 다른 곳에 저장하고 파일의 주소를 가지고 있는 것이 더 좋다.

그리고 라우터도 설정을 해줘야 한다.

userRouter
  .route("/edit")
  .all(protectorMiddleware)
  .get(getEdit)
  .post(uploadFiles.single("avatar"), postEdit);

우선 post 라우터에 사용을 할 예정이므로 post 라우터를 수정했다.

middleware를 사용하고 컨트롤러 함수를 사용하면 된다.
middleware를 작성하면 많은 항목이 뜨는데 우리는 1개의 파일만 사용하므로 single을 사용한다.

그리고 fieldName을 작성해 주어야 한다.
우리의 파일의 경우 form의 avatar에서 나오므로 이를 적어준다.

이런 식으로 작성하게 되면 request에 req.file 항목이 추가된다.

이제 req.file을 통해 업로드한 사진을 사용이 가능하다.
이렇게 하고 파일을 업로드해 보면 저장 폴더에 파일이 생성된다.

이렇게 생성한 파일의 경로를 req.file.path를 통해서 얻을 수 있다.
이 경로를 유저 업데이트에 넣어주자.

export const postEdit = async (req, res) => {
  const {
    session: {
      user: { _id, avatarUrl },
    },
    body: { name, email, username, location },
    file,
  } = req;
...
const updatedUser = await User.findByIdAndUpdate(
    _id,
    {
      avatarUrl: file ? file.path : avatarUrl,
...

사용자가 아바타를 사용하지 않은 경우 undefined가 되므로
이를 대비해서 이를 예외처리도 해줬다.
(세션에서 avatarUrl을 보내줬다.)

그리고 이렇게 받은 아바타를 표시해 보자.

block content
    img(src="/" + loggedInUser.avatarUrl, width="100", height="100")
    ...

유저 프로필 수정 페이지에 이미지의 주소를 받아와서 이미지를 만들어주었다.

그런데 아직 사진이 제대로 보이지 않는다.

이는 아직 브라우저가 서버에 있는 upload 파일에 접근이 불가능해서 그렇다.
브라우저가 서버의 어떤 폴더에든 접근이 가능하면 보안상 좋지 않기 때문에 막혀있다.
이를 해결해주어야 한다.

이는 static files serving을 활성화해서 해결이 가능하다.
폴더 전체를 브라우저에게 노출시킨다는 의미이다.
즉, 접근이 가능해진다.

우선 route를 생성해 주자.

app.use("/uploads")

그리고 폴더를 노출시키기 위한 설정을 해주자.
이를 위해서 express의 static이라는 기능을 사용한다.

app.use("/uploads", express.static("uploads"));

static 안에는 노출시키고자 하는 폴더를 작성해 주면 된다.

이제 사진이 보인다.

마무리

이번 시간에는 파일을 업로드해서 유저의 프로필을 만드는 방법을 알아보았다.

다음 시간에는 비디오를 업로드해 보자.

반응형