nodejs

🖼 nodejs 이미지 관련 모듈 multer 사용해보기

juju824 2020. 9. 14. 23:57

✔️ multer는 서버에서 사용하는 multipart/form-data 로 들어온 이미지를 처리하는 모듈이다

 

📌multer의 흐름

 

1. 클라이언트에서 이미지 파일을 업로드

2. 서버 내의 multer module을 거친다 

3. 코드 내에 multer-s3 를 연결지어 놓았기 때문에 내가 만들어놓은 s3 버킷으로 이미지 파일이 이동

4. s3 버킷의 저장 위치 URL을 server의 multer로 준다

5. multer에서 저장 위치 URL을 클라에게 전달

 

 

 

👇 아래의 코드 작성을 차차 따라해가면 multer 사용 뚝딱

multer를 사용하기 위해서는

2020/09/14 - [nodejs] - 🤖 S3는 어떻게 설정하고 생성해야 하나요? 

이 포스팅을 먼저 완료하고 진행해야 한다.

 

 

 

✔️ config/s3.json 

{
    "accessKeyId": "*****",
    "secretAccessKey": "*****",
    "region": "ap-northeast-2"
}

👉 이전 포스팅에서 생성한 S3 - IAM 이용해서 accessKeyId, secretAccessKey 복사해놓은거 붙여넣기

 

 

 

 

 

✔️ routes/user.js

const upload = require('../modules/multer');

router.post('/profile', AuthMiddleware.checkToken, upload.single('profile'), UserController.updateProfile);//user/profile

👉 기존에 있던 코드에 위 두줄을 추가

 

 

 

✔️ modules/multer.js

const multer = require('multer');

const multerS3 = require('multer-s3');

const aws = require('aws-sdk');

aws.config.loadFromPath(__dirname + '/../config/s3.json');

//config file 추가해야함

const s3 = new aws.S3();



const upload = multer({

storage: multerS3({

s3: s3,

bucket: 'puppy-diary', //bucket이름

acl: 'public-read',

key: function(req, file, cb){

cb(null, Date.now() + '.' + file.originalname.split('.').pop()); // 이름 설정

}

})

});

module.exports = upload;


 

 

 

 

 

✔️ controllers/user.js 

updateProfile: async (req, res) => {
        if (req.decoded === undefined) { 
            return res.status(statusCode.OK).send(util.fail(statusCode.OK, resMessage.EMPTY_TOKEN));
        }
        else{
        	const userIdx = req.decoded.userIdx;
        	// jwt 토큰 있는 사람만 가능하게끔 ==> AuthMiddleware.checkToken 가 routes에 있었으니
        	const profile = req.file.location;;
        	// location으로! => req.file.path 로 하면 undefined 로 뜬다

        	if (profile === undefined) {
        	    return res.status(statusCode.OK).send(util.fail(statusCode.OK, resMessage.NULL_VALUE));
        	}
        	// image type check
        	const type = req.file.mimetype.split('/')[1];
        	if (type !== 'jpeg' && type !== 'jpg' && type !== 'png') {
        	    return res.status(statusCode.OK).send(util.fail(statusCode.OK, resMessage.UNSUPPORTED_TYPE));
        	}

        	const result = await UserModel.updateProfile(userIdx, profile);
        	res.status(statusCode.OK).send(util.success(statusCode.OK, resMessage.UPDATE_PROFILE_SUCCESS, result));
    	}
 },

* const profile = req.file.location ===> req.file.location 으로 해야 오류가 안나온다

 

 

 

 

✔️ models/userModels.js 

updateProfile: async (userIdx, profile) => {
        let query = `UPDATE ${table} SET image = '${profile}' WHERE userIdx = ${userIdx}`;
        try {
            await pool.queryParam(query);
            query = `SELECT userIdx, profile FROM ${table} WHERE userIdx = ${userIdx}`;
            const result = await pool.queryParam(query);
            return result;
        } catch (err) {
            console.log('update profile ERROR : ', err);
            throw err;
        }
    },

 

 

$npm start 를 한 뒤 포스트맨 테스트를 다음과 같이 진행하면 

 

 

띠용 ❗️POST /user/profile 500 495.085 ms - 2346 (error msg 출력)

 

뭐가 문제일까... 500 에러는

- 서버 통신의 Timeout 시간 지연 
- 서버 트래픽 과부하
- 코드 문법 오류

보통 이 세가지 이유때문이라고 하길래 코드리뷰를 다시 시작해보았다

 

 

📌 nodejs 코드 리뷰 방법

 

1. routes 먼저 가서 메소드 확인, 사용되는 controller 확인 

2. cmd 와 클릭을 동시에 누르면 controller로 이동 

3. controller에서 model 확인 (cmd 와 클릭 동시에 누르기)

4. 디비 내에 제대로 컬럼이 추가되어 있는지 확인

 

 

코드는 제대로 되어있길래 포스트맨 오류 메시지 확인해보니

❗️AccessDenied: Access Denied

 

 

Access 관련 문제라면 S3 나 IAM 관련 문제 일 것 같은데 🤔

S3 정책 생성기에서 내가 getObject action 만 해주었는데

"Action": "s3:*"

전체로 바꿔 주었더니 access denied 가 풀렸다!

 

다시 포스트맨 테스트 진행

 

 

multer postman test

👉 jwt token 은 헤더에 정보로 넣어주고,

Body -> form-data -> key와 value ( 이때 key 는 file type으로 설정해야 한다)

 

status 200에 success!