[Django] S3 이미지 업로드

그냥·2022년 7월 12일
3

django

목록 보기
19/20

Django를 통해서 S3에 이미지 업로드를 하기 위해서는 아래 3가지 과정을 거쳐야 한다.

  1. AWS IAM user 셋업
  2. AWS S3 bucket 셋업
  3. Django에서 boto3를 사용하여 S3와 연결 및 파일 업로드



AWS IAM user 셋업

1) AWS 로그인 후 검색 창에 IAM 입력 후 IAM 페이지 접속

2) IAM 대시보드에서 사용자 클릭

3) 사용자 추가 클릭 후

  • 사용자 이름 입력
  • AWS 자격 증명 유형 선택 중 액세스 키 - 프로그래밍 방식 엑세스 항목만 클릭

4) 권한 설정

  • 기존 정책 직접 연결 클릭 후 정책 생성 클릭

  • 정책 생성 페이지에서 JSON 탭 클릭 후 아래 JSON 값 입력
  • example-bucket-name 부분은 나중에 S3 버켓을 생성했을때 해당 S3 버켓이름으로 바꾸어 준다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::example-bucket-name/*",
                "arn:aws:s3:::example-bucket-name"
            ]
        }
    ]
}
  • 새로운 policy를 생성 했으면 permission policy 페이지로 돌어가서 오른쪽 상단에 있는 refresh 버튼을 클릭하여 리스트를 refresh한 후 방금 만든 policy를 선택한후 next 버튼을 누른다.

5) policy 생성 후 Access Key ID, Secret Access Key 다운로드
새로운 유저 생성이 "Downlad.csv" 버튼을 클릭해서 "Access Key ID"와 "Secret Access Key"를 다운로드 받도록 한다. 지금 다운 받지 않으면 다시 다운 받거나 찾을 수 없음으로 꼭 다운 받아야 한다.




AWS S3 bucket 셋업

1) AWS S3 페이지로 가서 "Create bucket" 버튼을 클릭

  • 한 후 버켓 이름과 region을 선택
  • 모든 퍼블릭 엑세스 차단 해제: 원래는 보안상 이렇게 하면 안된다.
  • 다음을 눌러 버킷 생성을 완료한다.


2) Bucket Policy 수정

  • 생성된 버킷을 클릭하여 설정 페이지로 들어간다.
  • 상단의 "권한" 탭을 누르고 "버킷 정책"에서 편집을 누른다.
  • 아래 JSON을 복사 붙여 넣기 한다.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1507637373230",
            "Effect": "Allow",
            "Principal": {
                "AWS": "{user_arn}"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::{bucket_name}/*"
        },
        {
            "Sid": "Stmt1507637391106",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::{bucket_name}/*"
        }
    ]
}
  • {user_arn} 은 IAM user의 ARN 이다.
    - IAM 유저의 ARN은 IAM 페이지에서 users 페이지에 해당 유저를 클릭하면 나오는 페이지에서 확인 할 수 있다.
    - IAM > 왼쪽의 사용자 > 생성된 사용자 클릭 > 사용자 ARN
  • {bucket_name}은 각자 버켓의 이름이다.

3) CORS

  • 권한 생성 완료 후 아래에 있는 CORS에도 아래 JSON을 입력 후 save 해준다.
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ],
        "MaxAgeSeconds": 3000
    }



Django에서 boto3를 사용해서 S3에 이미지 업로드

boto3 설치

  • boto3는 파이썬용 AWS 라이브러리로 이를 먼저 설치해준다.
pip install boto3

S3ImgUploader 클래스 생성

class S3ImgUploader:
    def __init__(self, file):
        self.file = file

    def upload(self):
        s3_client = boto3.client(
            's3',
            aws_access_key_id     = settings.AWS_ACCESS_KEY_ID,
            aws_secret_access_key = settings.AWS_SECRET_ACCESS_KEY
        )
        url = 'img'+'/'+uuid.uuid1().hex
        
        s3_client.upload_fileobj(
            self.file, 
            "bucket_name", 
            url, 
            ExtraArgs={
                "ContentType": self.file.content_type
            }
        )
        return url
  • s3_client: boto3를 사용해서 s3에 로그인된 객체이다.
    - aws_access_key_id와 aws_secret_access_key은 IAM에서 유저 생성시 다운로드 받은 csv 파일에 있다.
  • url: 이미지를 업로드 할 경로이다. upload_fileobj의 인자로 들어간다.
    - url은 "폴더명" + "/" + "저장할 이미지 이름"으로 작성한다. 그런데 S3에 같은 이름이 있다면 업로드된 이미지가 덮어씌워 버린다. 그러므로 uuid를 사용한다.
    - uuid는 기본적으로 데이터를 고유하게 식별하는 데 사용되는 16바이트 길이의 숫자이다. uuid.uuid1().hex를 사용하여 랜덤하게 고유값을 만들어내서 이미지를 업로드 한다.
  • s3_client.upload_fileobj()
    - self.file: 업로드될 이미지
    - bucket_name: 버켓 이름
    - url: 위에서 작성한 url
  • ExtraArgs: {"ContentType": self.file.content_type}: 파일의 확장자를 가져오는 코드. 그대로 사용한다.
  • return url: url을 반환해서 이후 다른 곳에서 사용한다.

0개의 댓글

관련 채용 정보