TIL 25 | S3

saneeeeeeee_Ya·2021년 7월 14일
0

🛸

목록 보기
25/25
post-thumbnail

S3

아마존 S3는 아마존 웹 서비스에서 제공하는 온라인 스토리지 웹 서비스이다

S3 설정

퍼블릭 액세스 허용

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucketname/*"
        }
    ]
}

Django

s3.py

클래스 내에 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)

view.py

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)

Node.JS

s3.js

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()
            );
        },
    }),
});

view.js

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;
profile
🐜https://action2thefuture.github.io/🐜

0개의 댓글