개발/프로젝트

[엘리스트랙 SW 4기 | 2차 프로젝트] 트러블슈팅 - 미들웨어(multer 이미지 업로드 관련 이슈)

prpn97 2023. 6. 9. 00:00

https://github.com/expressjs/multer/blob/master/doc/README-ko.md

 

GitHub - expressjs/multer: Node.js middleware for handling `multipart/form-data`.

Node.js middleware for handling `multipart/form-data`. - GitHub - expressjs/multer: Node.js middleware for handling `multipart/form-data`.

github.com

발단

게시글 api를 만들면서 이미지를 업로드 부분을 구현하면서 multer을 미들웨어로 사용했는데,

multer는 이미지를 먼저 서버에서 지정한 디렉토리에 업로드한 후, 상황에 맞게 사용할 수 있다.

api를 구현한 후 이미지를 업로드해서 테스트하는데,

에러가 반환되었을 때에도 이미지가 지정된 디렉토리에 업로드된 것을 발견했다. 

멀터가 컨트롤러보다 먼저 미들웨어로 실행되기 때문에 이미지를 업로드하고 보는 것이다.

문제점

아래 사진과 같이 processImage 미들웨어 다음으로 컨트롤러가 실행된다. 

물론 컨트롤러에서 에러핸들러로 넘겨지면서 에러가 반환되면 컨트롤러 로직이 실행되지 않으니

실질적으로 이미지가 프론트에 전달되지는 않지만 이미지가 서버에 계속 쌓이게 된다. 

그래서 대부분 multer을 사용할 때 이미지가 서버에 업로드된 후, 컨트롤러에서 에러가 반환되면

업로드된 이미지를 삭제하는 방식으로 구현하는 것을 확인했다. 

 

 

여기서 한 가지 불편했던 점이 있었다.

 

이미지가 먼저 업로드되고 나서 여러 로직에 의해 이미지가 삭제되어야 한다면 

처음부터 로직이 작동하면 굳이 이미지를 업로드하고 삭제할 필요가 없다는 생각이 들었다. 

즉, 에러를 확인하고 나서 processImage미들웨어가 실행되면 되는 것 아닌가? 라는 생각이였다.

해결 과정

1. processImage 미들웨어를 가장 마지막 순서로 두는 경우. 

에러핸들러보다 밑에 processImage를 위치시켜서 에러핸들러의 에러를 감지하고

에러가 반환되지 않을 때 processImage가 실행되도록 한다. 

이렇게 하게 되면 이미지가 업로드되는 시점에서의 여러 에러들은 multer에서 firefilter을 사용하여 파일을 업로드하지 않고 건너뛸지 설정함과 동시에 클라이언트측에서 발생시킨 에러에 대해서도 감지하고 processImage로 넘길 수 있다고 생각했다. 

 

그런데 processImage를 마지막으로 두게 되면, 정작 컨트롤러에 있는 이미지 생성 로직이 더 먼저 실행되어서 로직에서도 파일을 찾을 수없고, 나중에 이미지를 업로드해도 사용할 수가 없다. 

 

 

2. 이미지를 업로드하기 전에 multer에서 에러를 확인하고 업로드를 막는 경우. 

모든 api는 에러처리를 try-catch를 통해 에러 핸들러로 보내고 있다.

에러 핸들러는 끝에서 모든 에러를 확인해야 한다.

예상치 못한 에러가 에러 핸들러 뒤에서 나온다면 별도의 처리를 해야 하기 때문이다.

 

에러 핸들러까지 가지 않더라도 processImage가 controller보다 먼저 작동되는 이상

controller에 있는 에러를 multer에서 확인할 수 있는 방법이 없다. 

 

 

 

결론적으로 이 문제를 해결하기에 앞서 api가 실행되는 순서를 떠올리며 구조를 정리해야 한다. 

 

지금은 multer에서 생성 - controller에서 파일 가공 및 전달 -전체 에러처리 의 과정을 거치는데,

multer에서 생성 자체를 막기 위해 현재의 3번의 과정을 어떻게 순서를 바꿔도 막을 수가 없다. 

당연히 생성이 되고, 전달할 때 에러를 확인하고 전달하지 않는 과정으로 진행되기 때문이다. 

 

해결 방법

간단하다. 맨 앞단에 별도로 에러처리를 하여 이미지가 생성되기 전에 에러를 반환하도록 했다. 

권한을 체크하는 에러처리에서 더 진행되지 않기 때문에 이미지를 업로드하기 전에 멈추게 된다.

 

 

느낀 점

처음 이 문제의 시발점은 권한이 없는 사용자가 게시글을 생성하려 하는 경우를 테스트하는 중

파일이 서버에 업로드되는 것을 발견하고 나서였다.

 

물론 게시글 생성 이전에 페이지에 접근조차 못하기 때문에 업로드를 할 수 없는게 정상이라,

실제로 서비스를 사용할 때 이런 이슈가 발생할 가능성은 아직 가늠이 되질 않는다. 

 

하지만 할 수 없어서 다른 대안으로 가리기보다 놓여진 문제점을 풀어내고 싶어서 구현하였다.

실제로 다른 api를 구현할 때 아키텍쳐를 더 자세히 이해하고 적재적소에 필요한 기능을 배치하면

니즈를 이해하고 파악하는데 수월할 것 같다는 생각이 들었다.

 

728x90