blog 프로젝트에서는 사용자가 게시글에 첨부할 사진을 저장해 놓을 공간이 따로 필요했다. 이를 위한 클라우드 스토리지 서비스를 찾아본 결과 AWS S3와 cloudinary 등의 서비스를 알게 되었다. 사용하기에는 cloudinary가 더 가볍고 편해보였지만 이 프로젝트를 결과적으로 AWS EC2에 deploy할 예정이었기 때문에 인프라 서비스 간 호환성을 생각해 AWS S3를 사용해 보기로 결정했다. AWS IAM 설정 및 s3 bucket 설정 방법에 관한 정보는 인터넷에 굉장히 많으니, 이 글에서는 설명을 생략하도록 하겠다.

아래는 이미지 업로드를 핸들링하는 함수이다.

    const handleImageUpload = async (e) => {
        const file = e.target.files[0];

        const s3 = new AWS.S3({
            accessKeyId: process.env.REACT_APP_AWS_ACCESS_KEY,
            secretAccessKey: process.env.REACT_APP_AWS_SECRET_ACCESS_KEY,
            region : 'ap-northeast-2',
        }); //s3 configuration

        const param = {
            'Bucket' : 's3.geunyoung.image',
            'Key' : `blog/image/${file.name}`,
            'ACL' : 'public-read',
            'Body' : file,
            'ContentType': 'image/png'
        }; //s3 업로드에 필요한 옵션 설정

        s3.upload(param, (err, data) => { //callback function
            if(err) {
                console.log('image upload err : ' + err);
                return;
            }

            const imgTag = `<img src=${data.Location} width="100%" />`;

            const action = {
                type : 'content',
                value : `${postState.content} \n ${imgTag}`
            };
            postDispatch(action)
        });
    };

굉장히 간단하다. AWS에서 IAM을 생성한 후 액세스 키를 발급받고 S3 bucket을 생성한다. 그 다음 관련 정보를 적절히 실어서 s3 서버에 업로드 요청을 보내면 된다. 그런 다음 이미지가 업로드된 주소를 img tag로 감싸서 브라우저에 적절히 뿌려주면 끝!