AWS S3 서비스를 이용해 image를 upload하는 End-Point를 만드려고 합니다.
이를 위해 준비사항은 다음과 같습니다.
AWS IAM(Identity and Access Management)이란 AWS resource 보안 서비스입니다.
AWS 서비스와 리소스에 대한 액세스를 안전하게 관리할 수 있습니다.
{
"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"
]
}
]
}
example-bucket-name 부분은 나중에 S3 bucket을 생성했을때,
해당 S3 bucket이름으로 바꾸어줍니다.
[STEP 3] 정책 이름과 설명 추가
[STEP 4] 정책 생성
User 생성
[STEP 1] IAM dashboard에서 사용자 클릭
[STEP 2] 사용자 추가 버튼 클릭
[STEP 3] Programmatic Access 항목 체크
[STEP 4] 만들어 놓은 정책을 선택하고 다음으로 넘어가기
[STEP 5] PASS
[STEP 6] PASS
[STEP 7] 새로운 유저 생성이 완료되면 “Download.csv” 버튼을 클릭해서 유저의 “Access Key ID”와 “Secret Access Key”를 다운로드 받기(이때 다운 받지 않으면 다시 다운로드 받을 수 없으므로 꼭 다운로드 받아야 함)
Amazon S3 bucket 이란,
public cloud storage resource입니다.
Amazon S3 buckets는 object를 저장합니다.
object는 data와 descriptive metadata로 구성됩니다.
file folder와 같은 역할을 합니다.
AWS S3 bucket setting
[STEP 1 ~ 2] AWS S3 페이지로 가서 “Create bucket” 버튼을 클릭한 후 버켓 이름과 region을 선택
[STEP 3] “Block all public access”를 uncheck
[STEP 4 ~ 5] 버켓 생성이 완료되면 해당 버켓을 클릭해서 버켓의 설정 페이지로 이동
[STEP 6] 상단의 “Permission(권한)” 탭에서 “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,
{bucket_name}은 bucket의 이름입니다.
IAM 유저의 ARN은 IAM 페이지 -> users 페이지 -> 해당 유저를 클릭하면
나오는 페이지에서 확인 할 수 있습니다.
[STEP 6] save 버튼 클릭
Public access warning은 일단 무시하겠습니다. 원칙적으로는 S3는 public access를 주지 않는것이 보안상 좋습니다. S3는 private하게 막고 S3 앞에 CloudFront를 붙여 CDN 기능을 구현하는것이 정석입니다.
[STEP 7] “CORS configuration” 버튼을 눌러서 아래와 같이 CORS 설정 후 save
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
이제 기본적인 준비는 끝났습니다.
이제 formdata를 보내면 url로 돌려주는 End-Point를 만들어 보겠습니다.
그전에 python용 AWS 라이브러리인 boto3가 필요합니다.
pip install boto3
boto3를 설치하고 다음과 같이 view를 작성합니다.
import boto3
class FileToURL(View):
s3_client = boto3.client(
's3',
aws_access_key_id={aws_access_key_id},
aws_secret_access_key={aws_secret_access_key}
)
def post(self, request):
for file in request.FILES.getlist('file'):
self.s3_client.upload_fileobj(
file,
{bucket-name},
file.name,
ExtraArgs={
"ContentType": file.content_type
}
)
file_urls = [f"https://s3.ap-northeast-2.amazonaws.com/{bucket-name}/{file.name}" for file in request.FILES.getlist('file')]
return JsonResponse({'files':file_urls}, status=200)
{aws_access_key_id}와 {aws_secret_access_key}는
1. AWS IAM
에서 사용자를 생성하고
다운로드 받은 credentials.csv 파일에서 확인할 수 있습니다.
file_url에서 {bucket-name}은 2. AWS S3 Bucket
에서 생성한 Bucket의 이름을 적어주면 됩니다.
또한, Front-End에서 Back-End API로 formdata를 보내게 되면
request.FILES에 file들이 담겨오게되는데
이때, request.FILES는 MultiValueDict 입니다.
MultiValueDict의 경우, getlist(key) 메서드를 사용해서 value에 해당하는 list를 받아올 수 있습니다.
간단하고 명쾌하게 정리를 너무 잘해주셔서 큰 도움 되었습니다.
감사합니다.