컴퓨터/웹 : JS

[Node.js] Cloudinary이용 이미지 삽입하기

도도새 도 2023. 3. 16. 19:09

웹에 이미지 삽입

 

드디어 개강을 하였다. 이제 개인 프로젝트를 할 시간이 없을 거라 생각했던 우려와 달리 시간이 꽤나 주어졌다. 우선 플러터로 진행하기로 한 졸업과제 프로젝트가 엎어졌다. 플러터의 미래에 대한 불확실성이 문제였다. 팀원들의 배려 비슷한 무언가로 내 기술 스택으로 졸업 과제를 진행하게 되었다. 노드 JS를 이용한 인공지능 웹이다.

 

아무튼 이렇게 주어진 시간을 알차게 써야한다. 오늘은 Cloudinary를 이용해 사진을 넣도록 하겠다. 클라우디너리는 클라우드 기반의 이미지 및 동영상 관리 처리 서비스를 제공하는 회사이다. 이를 이용하여 나는 웹에 올리는 이미지 파일들을 관리하고, 규격에 맞게 처리하여 사용자에게 보여주고자 한다.

 

웹에서 사용되는 모든 것(데이터 베이스 포함)은 로컬 저장소에 저장하여 사용하기 힘들다. 그러므로 이러한 서비스를 많이 사용하여 개발하게 될 것이다.

 

From - 서버 연동

 

form에서 typefile로 설정하고 post요청을 하면, 처음에는 작동하지 않는다. form 타입에는 enctype이라는 속성이 있는데, 서버로 데이터를 전송할 때 데이터의 인코딩 방식을 정의한다.

 

여기서 파일, 이미지를 보낼 경우 multipart/form-data를 값으로 하여 보내게 된다.

 

여기서 multer라는 미들웨어를 사용하게 되는데, 만약 이를 사용하지 않으면 multipart/form-data를 선택했더라도 url 형식으로 데이터를 전송하게 되어 빈 객체를 전송하게 된다.

 

app.use(express.urlencoded({extended:true}));

//이 미들웨어에서 application/x-www-form-urlencoded MIME 타입으로 인코딩되어 전송되도록 설정한 바 있기 때문이다.(이 미들웨어는 URL-encoded 데이터를 파싱하고, req.body 데이터에 저장해 준다. 이 덕분에 나는 req.body으로 데이터에 접근하였다.)

 

 

, multer는 이와 비슷하다. multipart/form-data형식으로 파싱을 돕는다.

 

https://www.npmjs.com/package/multer

 

multer

Middleware for handling `multipart/form-data`.. Latest version: 1.4.5-lts.1, last published: 10 months ago. Start using multer in your project by running `npm i multer`. There are 3668 other projects in the npm registry using multer.

www.npmjs.com

 

npm install multer로 멀터를 설치한다.

 

이후 아래의 코드를 추가한다.

const multer = require('multer');

const upload = multer({ dest: 'uploads/' });

//dest는 저장 될 장소...임시로 로컬로 설정

이제 아무 때나 upload 미들웨어를 추가할 수 있게 된다. 예를 들어 upload.array()를 작성하면 여러 장의 파일이, upload.single()로 하면 하나의 파일(여기서는 사진)이 저장 될 것이다.

처리된 파일은 req.files로 저장이 된다고 한다.

 

         <form action ="/cafe"method ="POST"enctype ="multipart/form-data">

 

이렇게 폼의 enctype을 바꾸었다. 또한 폼 내부 input은 아래와 같이 설정하였다.

 

             <input type ="file"name ="photos" multiple >

 

실제로 폼에 데이터를 넣고 날려보면, dest의 주소로 폴더가 생기고 그 내부에 파일이 생겨있다.

dest

앞서 파일은 req.files에 저장된다고 했다. 콘솔에 찍어보면 아래와 같은 형태를 가진다.

 

Cloudinary 연동

 

이제 이 파일을 웹 서비스를 이용하여 저장할 것이다. 사진을 저장 관리해주는 서비스로 Cloudinary라는 사이트가 있는데, 이를 이용할 예정이다.

 

이에 다양한 이유가 있는데, 그 중 하나가 자체적으로 사진과 관련된 다양한 기능을 지원해준다는 것이고, 또 하나는 내가 이미 써 봐서 상대적으로 쉽게 할 수 있기 때문이다.

 

https://cloudinary.com/

이 사이트에 로그인을 한 후 Dash보드로 가면 API키를 받아 사용 가능하다.

 

이 과정에서 또 api키를 받아서 사용하는데, 이전에 카카오 맵 api키를 숨기지 않은 것이 생각났다. 이번에 dotenv를 이용해 API 비밀 키를 숨기도록 한다.

 

npm I dotenv로 설치를 한다.

dotenv?

 

dotenvNode.js프로젝트의 환경 변수 관리를 위한 패키지이다. 이를 이용하여 민감한 정보(데이터베이스 비밀번호, API키 등)을 외부에 노출하지 않은 채 코드 안에서 관리 가능하다.

 

 이를 이용하기 위해 .env 파일을 생성하고, 여기에 민감한 정보를 저장한다. 이렇게 함으로써 코드 내에서 process.env객체를 통해 해당 값을 가져와 사용할 수 있다.

 

.env에 키:valueAPI정보들을 저장한다.

 

이제 cloudynary 패키지와 multer-storage-cloudinary를 이용해서 멀터로 받은 정보를 클라우디너리에 저장해야한다.

https://www.npmjs.com/package/multer-storage-cloudinary

 

multer-storage-cloudinary

A Cloudinary multer storage engine. Latest version: 4.0.0, last published: 3 years ago. Start using multer-storage-cloudinary in your project by running `npm i multer-storage-cloudinary`. There are 8 other projects in the npm registry using multer-storage-

www.npmjs.com

 

아래와 같이 코드를 작성하였다.

 

const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
 
cloudinary.config({
    cloud_name:process.env.CLOUDINARY_CLOUD_NAME,
    api_key:process.env.CLOUDINARY_KEY,
    api_secret:process.env.CLOUDINARY_SECRET
});
 
const storage = new CloudinaryStorage({
    cloudinary: cloudinary,
    params:{
        folder:'CafeBara',
        allowedFormats: ['jpeg', 'png', 'jpg']
    }
});
 
module.exports = {
    cloudinary,
    storage
}

 

그리고 multer-storage-cloudinary 문서의 아래에 해당하는 부분을 바꾼다. , dest라고 되어있던 것을 storage로 변경한다.

storage

multer문서를 보면 dest가 아니라 storage를 사용하여도 저장할 장소를 나타낸다는 것을 말해준다.

 

즉 아래와 같이 코드를 바꿔준다.

const upload = multer ({ storage });

 

 

결과

 

결과

 

그런데.... 여기서 한참을 헤맸다... 아무리 찾아보고 문서를 뒤져봐도 원인을 찾지 못하였다. 설마 키에 오타가 있나 살펴보기도 했다. 그러다 이전에 깨달은 사실을 생각했다. 문제는 대체로 내가 쉽게 하고 넘어간 지점에서 발생했다고.

 

경로를 보았다.

 

 

const {storage } = require ('cloudinary');

 

위가 본래의 코드였다. 작성할 때는 아무 생각 없이, 직접 cloudinary라는 폴더를 만들고 안에 index.js라는 파일을 넣어 관련 모듈들을 설정해 주었다.

 

그러나 지금 보니 require(‘cloudinary’)를 하면 npm으로 install한 모듈을 가져오게 된다. , 라이브러리를 가져오게 된다.

 

해결책으로 1. 이름을 바꾸던가, 2.절대경로를 사용하던가, 3. 상대 경로를 명시적으로 표현하면 되겠다.

 

 

const {storage } = require ('./cloudinary');

나는 3번을 선택해 위처럼 고쳤다. 본래라면 ./aaaa는 같은 경로를 나타내지만, 여기서는 잘못 사용하였다.

 

아무튼 이렇게 하여 사진 업로드가 가능하게 되었다.

사진 업로드 완료

오늘은 생각보다 시간이 많이 잡아먹혀서 여기까지만. 참 아쉽다.