아마존 S3는 아마존 웹 서비스에서 제공하는 온라인 스토리지 웹 서비스이다
퍼블릭 액세스 허용
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*"
}
]
}
클래스 내에 init 생성자를 이용하여 클라이언트를 저장
클라이언트에는 아마존 서비스, 액세스 키값, 액세스 ID가 객체 안에 저장한다
s3에 파일을 업로드하기위해서는 upload_fileobj 함수를 이용한다
해당 함수는 파일과 파일명, 폴더명(경로), 파일의 타입 등을 저장할 수 있다
파일의 url를 DB에 저장 후 해당 파일의 후처리가 가능해진다
키값을 이용하여 해당 파일을 수정
url을 이용하여 해당 파일을 클라이언트에 전달하여 불러올 수 있다
from my_settings import AWS_STORAGE_BUCKET_NAME, AWS_S3_CUSTOM_DOMAIN
class S3Client:
def __init__(self, s3_client):
self.s3_client = s3_client
def upload(self, file, file_name, FOLDER_NAME):
self.s3_client.upload_fileobj(
file,
AWS_STORAGE_BUCKET_NAME,
f"{FOLDER_NAME}/{file_name}",
ExtraArgs={"ContentType": file.content_type}
)
file_urls = f"https://{AWS_S3_CUSTOM_DOMAIN}/{FOLDER_NAME}/{file_name}"
return file_urls
def delete(self, file_name):
self.s3_client.delete_object(
Bucket=AWS_STORAGE_BUCKET_NAME,
Key=file_name)
boto3를 이용하여 s3를 이용할 수 있다
유저가 허용된 유저인지 판단을 하고 토큰 내의 유저 정보를 불러온다
파일의 이름은 중복된 파일 이름을 허용하지 않도록 uuid4를 이용한다
import boto3
from uuid import uuid4
client = boto3.client(
's3',
aws_access_key_id = MY_AWS_ACCESS_KEY_ID,
aws_secret_access_key = MY_AWS_SECRET_ACCESS_KEY
)
class ProfileUpload(View):
@LoginRequired
def post(self, request):
try:
file = request.FILES.get('profile_file')
user = request.user
if not file:
return JsonResponse({'massage':"none file"}, status=404)
s3_client = S3Client(client)
file_name = uuid4().hex
FOLDER_NAME = "profile"
file_urls = s3_client.upload(file, file_name, FOLDER_NAME)
user.profile_url = file_urls
user.save()
return JsonResponse({'massege':'create'}, status=200)
except KeyError:
return JsonResponse({"message" : "key error"}, status=400)
multer와 multer-s3를 이용하여 파일이 전달되는 요청을 받을 수 있다
aws-sdk를 이용하여 s3를 이용할 수 있다
uuid를 이용하여 파일 이름의 중복을 없애준다
multerS3에 버킷이름, 파일 타입, 키값 등 저장 및 전달한다
cb는 next와 비슷한 함수이다
다음 콜백함수에게 메타데이터와 키값을 전달한다
const multer = require("multer");
const multerS3 = require("multer-s3");
const aws = require("aws-sdk");
const { v4 } = require("uuid")
require('dotenv').config()
const BUCKET_NAME = process.env.BUCKET_NAME
const s3 = new aws.S3({
accessKeyId: process.env.AMAZONE_ACCESS_KEY_ID,
secretAccessKey: process.env.AMAZONE_SECRET_ACCESS_KEY,
region: process.env.AMAZONE_REGION,
});
exports.upload = multer({
storage: multerS3({
s3: s3,
bucket: BUCKET_NAME,
contentType: multerS3.AUTO_CONTENT_TYPE,
acl: "public-read",
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(
null,
"profile/" + v4() + "." + file.originalname.split(".").pop()
);
},
}),
});
s3.upload.single 미들웨어를 통하여 파일을 받는다
키값을 지정할 수 있다
const express = require("express");
const router = express.Router();
const s3 = require("./S3");
router.post(
"/profile",
s3.delete,
s3.upload.single("profile"),
Profile.uploadProfile
);
module.exports = router;