maruzzing님의 블로그글을 십분참고하여 구현한 기능이라는 것을 미리 밝혀놓는다.
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": ["arn:aws:s3:::BUCKET_NAME/*"]
}
]
}
npm install --save aws-sdk
npm install --save multer-s3
//utils/s3.js
const AWS = require('aws-sdk');
var multer = require("multer");
var multerS3 = require("multer-s3");
const path = require("path")
const dotenv = require('dotenv')
dotenv.config()
const { AWS_config_region, AWS_IDENTITYPOOLID } = process.env
const bucket = 본인 버킷 이름
AWS.config.update({
region : AWS_config_region,
credentials : new AWS.CognitoIdentityCredentials({
IdentityPoolId: AWS_IDENTITYPOOLID
})
})
const s3 = new AWS.S3({
apiVersion: "2006-03-01",
params: {Bucket: bucket}
});
const upload = multer({
storage: multerS3({
s3: s3,
bucket: bucket,
contentType: multerS3.AUTO_CONTENT_TYPE, // 자동으로 콘텐츠 타입 세팅
acl: "public-read",
key: (req, file, cb) => {
let extension = path.extname(file.originalname)
cb(null, 'profileimage/'+Date.now().toString()+extension);
}
}),
limits: { fileSize: 5 * 1024 * 1024 } // 용량 제한
});
module.exports = upload
//routes/UserRouter.js
const express = require('express')
const passport = require('passport')
const router = express.Router()
const { body } = require('express-validator')
const upload = require('../utils/s3') //업로드 모듈을 불러온다.
const { UserController } = require('../controllers')
const { validateToken } = require('../middlewares')
router.post(
"/mypage",
validateToken,
upload.single('profile_picture'), //여기서 업로드가 이루어진다.
UserController.addInfo,
)
module.exports = router
case1: 하나의 필드명을 가지는 여러개의 파일을 받을 때
router.post(
"/mypage",
validateToken,
upload.array('profile_picture', 5), //이미지 최대 수를 입력
UserController.addInfo,
)
case2: 여러개의 필드명을 가지는 여러개의 파일을 받을 때
router.post(
"/mypage",
validateToken,
upload.fields([
{ name: 'profile_picture', maxCount: 1 },
{ name: 'company_pictures', maxCount: 5 },
)],
UserController.addInfo,
)
//controllers/UserController.js
require("dotenv").config();
const { AUTH_TOKEN_SALT } = process.env
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const { UserService } = require('../services')
const { errorWrapper, errorGenerator } = require('../errors')
const addInfo = errorWrapper(async(req, res) => {
const { id: userId } = req.foundUser //지금 로그인한 회원의 정보로 접근
const requestedFields = req.body //request로 들어온 문자열을 저장
const profile_picture = req.file.location //request로 들어온 파일의 경로를 저장. 파일의 수가 많다면 files[index_num] 혹은 files[field_name]
const addInfo = await UserService.updateInfo({ userId, requestedFields, profile_picture })
res.status(201).json({
message: 'information successfully added'
})
})
module.exports = addInfo //export하는 다른 모듈에 추가해준다.
//services/UserService.js
const updateInfo = (async (fields) => {
const { userId, requestedFields, profile_picture } = fields
console.log(profile_picture)
return prisma.users.update({
where: {
id: Number(userId),
},
data: {
phone_number : requestedFields.phone_number,
profile_picture
}
})
})