몽고DB Blob 파일 저장하고 Read 하기 [TOY / Simple-SNS]

알락·2022년 11월 16일
0

Simple-SNS

목록 보기
3/9

진행 동기

클라이언트에서 이미지 미리보기, 그리고 메시지 작성까지 구현이 완료되고 욕심이 생겼다. SNS이기 때문에 이미지를 저장하여 보여주는 것은 당연히 구현되어 있어야 한다고 생각했다. 업로드한 이미지를 다른 사람들도 서버에 요청을하여 이미지를 볼 수 있는 기능을 제공하기 위하여 서버 작업을 해주었다.

기능

이번에는 Back-End와 DBMS 측을 구현한다. 클라이언트에서 넘겨준 image와 message를 서버에서 받아 필요한 형태로 가공한 이후 mongoDB에 저장한다.
이후 클라이언트에서 서버에 요청이 올 때마다 저장된 image를 데이터베이스에서 가져올 수 있게 한다.

구현

[Model 부분 변경]

// 스키마에 image 필드를 추가해줬다.
// Blob 파일이지만, 현재 넘어오는 값은 base64의 문자열이어서 String으로 타입 지정해줬다. 
const messageSchema = new mongoose.Schema({
    userId : String,
    content : String,
    image : String,
    createdAt : Date,
})

[Controller 부분 변경]

const send = async (req, res)=>{
        const newMSG = req.body.message;
		
  		// 추가된 명령
        newMSG.image = newMSG.image || null;
        
        const currentTime = new Date();
        newMSG.createdAt = currentTime.toISOString();
        
        const result = await Message.create(newMSG, (err, result)=>{
            if(err) return err;
            else return result;
        })

        return res.status(200).send({msg : result});
    }

[express 서버 설정 변경]

//...생략

app.use(express.json({limit:"10mb"}));

//...생략

위의 서버 설정은 중요하다. 이미지 파일은 텍스트만 넘어오는 형식과는 다르게 데이터 크기가 크다. 이 때문에 기본값으로 설정되어있는 "100kb"보다 훨씬 많은 "10mb"를 지정해주었다.

limit을 "10mb"로 지정하면서 보안의 문제가 있을 수도 있다는 생각을 해봤다. 현재 파일의 형식을 클라이언트에서만 필터링을 해주고 있기 때문에, 서버에 직접적으로 공격이 되면 문제가 되는 스크립트가 저장될 여지도 있다.

개선할 점

이미지는 기존의 텍스트만 DB에 저장하는 것과는 결이 다른 문제를 안겨줬다. 텍스트에 비해 이미지는 데이터 크기가 크다. 위의 데모 영상을 봐도 알겠지만 SPA인데도 불구하고 업로드를 한 이후 DB와 연동이 안되고 있어 새로고침을 하고 있다.
데이터베이스에 저장하는 속도가 지연되다 보니까 기존의 업로드 이후 모든 데이터 가져오기 방식은 통하지 않는 것 같다.
업로드 이후 바로 해당 화면에서 추가된 컨텐츠를 확인할 수 있게 프로젝트를 개선해보려고 한다.

악의적인 스크립트를 이미지 대신하여 제출할 경우 데이터베이스 저장하기 이전 Back-End에서 취할 수 있는 행동을 고민해봐야 할 것 같다.

profile
블록체인 개발 공부 중입니다, 프로그래밍 공부합시다!

2개의 댓글

comment-user-thumbnail
2022년 11월 18일

DB 서버가 가장 고가의 장비이고, 트래픽이 몰릴경우 대부분의 병목은 DB에서 일어나므로, DB에는 미션크리컬한 정제된 데이터만 저장하고, 이미지나 영상같은 blob 데이터는 외부에 저장하는것이 바람직하다고 알고 있습니다. AWS S3 같은데 많이 저장하는 것 같더라구요. 유어클래스에서도 이미지는 s3 사용했구요.

그리고 트윗 보내기 버튼을 클릭하고 이미지를 본문과 함께 db에 저장하는 방식이 아니라, 이미지 파일 선택이 완료되자마자 브라우저에서 비동기 axios요청으로 파일 업로드 전용 라우터에 업로드하면 사용자가 글을 작성하는 동안 이미지는 업로드 되고 있으므로 UX를 향상시킬수 있는 설계가 될거라고 생각합니다. (Node.js 교과서 개정 2판 에서 배웠어요)

재밌는 작동영상이랑 글 종종 잘 보고 갑니다. ㅎㅎ

1개의 답글