어플리케이션을 개발하는 과정에서 스태틱한 파일을 처리하는 로직을 구현하는 것은 프론트엔드, 백엔드 입장에서 생각보다 매우 귀찮은 일입니다. 파일의 종류와 크기에 따라서 여러가지 예외의 경우를 처리해야 하는 경우도 있고 사용자 입장에서 진행되는 시간이 지루하게 느낄 수 있으므로 클라이언트에서 여러가지 효과를 통해서 사용성을 높여주기도 합니다.
이번 글은 얼마전에 끝난 프로젝트를 진행하면서 고안한, 스태틱한 파일들을 전송하는 패턴을 변경, 최적화하게된 내용을 공유하기 위한 글입니다. 진행한 프로젝트에서 제가 만든 어플리케이션은 한개에 10Mb 가 넘는 사진들이 200장 정도, 별도의 처리과정을 거쳐나온 2~8Gb 정도의 큰 파일들을 업로드하고 다운로드하는 작업이 빈번한 어플리케이션으로 사용자의 편의성과 요금절약(?)을 위해 최적화 패턴을 도입해야할 필요성이 있었습니다.
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData();
formData.append("file", file);
formData.append("data", {
name: "data-file"
});
try {
const res = await axios.post("/api/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
} catch (err) {
console.log("Error: ", err);
}
};
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'REGION'});
// Create S3 service object
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
// call S3 to retrieve upload file to specified bucket
var uploadParams = {Bucket: process.argv[2], Key: '', Body: ''};
var file = process.argv[3];
// Configure the file stream and obtain the upload parameters
var fs = require('fs');
var fileStream = fs.createReadStream(file);
fileStream.on('error', function(err) {
console.log('File Error', err);
});
uploadParams.Body = fileStream;
var path = require('path');
uploadParams.Key = path.basename(file);
// call S3 to retrieve upload file to specified bucket
s3.upload (uploadParams, function (err, data) {
if (err) {
console.log("Error", err);
} if (data) {
console.log("Upload Success", data.Location);
}
});
// 출처: aws-documentation https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html
AWS Identity and Access Management(IAM)은 AWS 리소스에 대한 액세스를 안전하게 제어할 수 있는 웹 서비스입니다. IAM을 사용하여 리소스를 사용하도록 인증(로그인) 및 권한 부여(권한 있음)된 대상을 제어합니다.
Amazon Cognito를 사용하면 웹과 모바일 앱에 빠르고 손쉽게 사용자 가입, 로그인 및 액세스 제어 기능을 추가할 수 있습니다. Amazon Cognito에서는 수백만의 사용자로 확장할 수 있고, Apple, Facebook, Google 및 Amazon과 같은 소셜 자격 증명 공급자와 엔터프라이즈 자격 증명 공급자(SAML 2.0 및 OpenID Connect 사용)를 통한 로그인을 지원합니다. - aws cognito 소개글
A user pool is a user directory in Amazon Cognito. With a user pool, your users can sign in to your web or mobile app through Amazon Cognito. Your users can also sign in through social identity providers like Google, Facebook, Amazon, or Apple, and through SAML identity providers. Whether your users sign in directly or through a third party, all members of the user pool have a directory profile that you can access through a Software Development Kit (SDK).
Amazon Cognito identity pools (federated identities) enable you to create unique identities for your users and federate them with identity providers. With an identity pool, you can obtain temporary, limited-privilege AWS credentials to access other AWS services. Amazon Cognito identity pools support the following identity providers:
- Public providers: Login with Amazon (identity pools), Facebook (identity pools), Google (identity pools), Sign in with Apple (identity pools).
- Amazon Cognito user pools
- Open ID Connect providers (identity pools)
- SAML identity providers (identity pools)
- Developer authenticated identities (identity pools)
유저가 로그인 과정을 거쳐 코그니토로부터 크레덴셜을 가져오게 되는 로직을 간단하게 보여드리겠습니다.
코그니토는 소셜로그인 기능을 제공하지만 여기선 편의상 아이디/패스워드 로그인 방식을 전제로 진행했습니다.
S3업로드 시 presigned URL 을 고려 안한 이유가 있을까요?