내일배움캠프

230517 aws lambda 함수를 호출하여 이미지 업로드

Neda 2023. 5. 17. 20:53

파일 업로드 

HTML에서 서버로

form에서 파일을 전송할 때는 enctype="multipart/form-data" 는 필수 속성이다

<form
    method="post"
    action="/api/member"
    enctype="multipart/form-data"
    onsubmit="createMember(event)"
>
...
<input
    type="file"
    id="image"
    name="image"
    accept=".jpg, .jpeg, .png"
    multiple
/>
...
<input type="submit" value="생성하기" />
</form>

formdata에 전부 담아서 서버로 보낸다.

async function createMember(event) {
    event.preventDefault();
    const formData = new FormData(event.target);
    await fetch("/api/member", {
        method: "POST",
        body: formData,
	});
}

 

 

서버에서 저장하기

서버에서는 파일이 없는지 확인하고,

없거나 비어있다면 기본 이미지의 url을 사용한다.

파일이 있다면 upload_image() 함수를 실행한다.

그 결과로 받은 url을 사용한다.

...
id = str(uuid.uuid4())
image = request.files['image']
if (is_empty_file(image)):
	photo_url = '<defaultImageUrl>';
else:
	photo_url = upload_image(id,image)
...

upload_image()

upload_image는 파일의 확장자를 먼저 체크한다.

파일의 주소를 만들기 위해 사용자 id와 파일의 확장자,파일 데이터를 lamdba 함수로 보낸다.

여기서 파일 이름은 사용하지 않는다.

파일 이름은 lambda 함수에서 랜덤으로 사용했다.

파일 내용은 문자열로 전달하기 위해 인코딩 과정이 필요하다.

lamdba함수는 s3에 파일을 업로드하고 body에 넣어 url을 반환한다.

def upload_image(id,image):
    try:
        filename =image.filename
        if not is_allowed_file(filename):
            raise InvalidExtensionError
        payload = {
            'id': id,
            'extension': filename.rsplit('.', 1)[1],
            'data': base64.b64encode(image.read()).decode('utf-8')
        }
        response = lambda_clinet.invoke(
            FunctionName='save-image-to-s3',
            InvocationType='RequestResponse',
            Payload= json.dumps(payload)
        )
        response_payload = response['Payload'].read().decode('utf-8')
        response_payload = json.loads(response_payload)
        return response_payload['body']
    except Exception as e:
        raise ImageUploadError

 

 

boto3에서 lambda 함수 호출하기

 

invoke - Boto3 1.26.135 documentation

Previous get_waiter

boto3.amazonaws.com

aws s3 객체 생성하기

 

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/preview/client/s3/command/PutObjectCommand/

 

docs.aws.amazon.com


lamdba함수도 apigateway를 사용하려고 했는데 인증 부분이 익숙하지 않아

일단은 boto3로 진행했다. 덕분에 깔아야 하는 라이브러리가 하나 더 늘어났다.

백엔드를 다룰 때 특히나 파일은 파일 이름부터 확장자, 데이터까지 예외적인 경우가 많아

어느 예외를 잡아야 하는지 감이 안잡힌다.

찾아보니 파일이 멀웨어인지, 파일이 안전한지 등도 확인하는 것 같던데

정말  데이터나 서버를 다룰 때는 신중해야 하는 것 같다.