[AWS] S3 (Simple Storage Service)
S3๋ ์๋ง์กด์์ ์ ๊ณตํ๋ ์ ์ฅ๊ณต๊ฐ ์๋น์ค๋ค.
๊ทธ๋ฅ ํ์์ ์ฐ๋ ๋๋กญ๋ฐ์ค, ๊ตฌ๊ธ ํด๋ผ์ฐ๋ ์ฒ๋ผ ๋ฆฌ์์ค ํ์ผ๋ค์ ์ฌ๋ ค๋๊ณ ์กฐํํ ์ ์๋๊ฑด๋ฐ, ์๋ง์กด์ ์๋น์ค์ ๋ฐ๋ก ์ฐ๋๋๋ค๋ ์ ์ด ๋ค๋ฅด๋ค.
๋ณดํต ์ด๋ฏธ์ง๋ ๋์์ ๊ฐ์ ๋ฏธ๋์ด ํ์ผ๋ค์ ์ ์ฅํ ๋ ์ฌ์ฉํ๋ค.
์ข ๋น์ผ ํธ์ด๊ธด ํ์ง๋ง ๊ฐ์ํ ๋งํ ์ ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ฅํ ์ฉ๋์ ๋ํด์ ๋ค๋ฌ์ด ์๊ธ์ด ๋ถ๊ณผ๋๊ณ , ํ์ผ์ ์ฌ๋ฆฌ๊ฑฐ๋ ์กฐํํ ๋ ๋ฐ์ํ๋ ํธ๋ํฝ์ ๋ํด์๋ ์๊ธ์ด ๋์จ๋ค.
๋ฒํท ๋ง๋ค๊ธฐ
S3๋ ๋ฒํท์ด๋ผ๋ ๋จ์๋ก ๊ด๋ฆฌ๋๋ค.
๊ทธ๋ฅ ๊ฐ์์ ๊ฒฉ๋ฆฌ๋ ์ ์ฅ๊ณต๊ฐ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.

์ง์ ํ ์ต์
์ด ๊ทธ๋ ๊ฒ ๋ง์ง๋ ์๋ค.
์ด๋ฆ์ ์ ์ง๊ณ

์ด๋ฏธ์ง๋ฅผ ๋๊ตฌ๋ ๋ณผ ์ ์๊ฒ ์ด์ด์ค ํ์๊ฐ ์๋ค๋ฉด ํผ๋ธ๋ฆญ ์ก์ธ์ค ์ฐจ๋จ์ ๋นํ์ฑํํ๋ค.

๋ง์ฝ ํ์ผ์ด ๋ฎ์ด์์์ง๊ฑฐ๋ ์ง์์ง๋๊ฒ ๋์ฐํ๊ฒ ์ซ๋ค๋ฉด ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ์ฌ์ฉํด๋ ์ข๊ฒ ๋ค.

๊ทธ๋ผ ์ด๋ ๊ฒ ๋ฒํท ํ์ด์ง๊ฐ ์์ฑ๋๋๋ฐ
์
๋ก๋ ๋ฒํผ์ ๋๋ฅด๋ฉด ํ์ผ์ ์
๋ก๋ํ ์ ์๊ณ , ํ์ผ์ ๋๋๊ทธํด์ ์ฌ๋ฆด ์๋ ์๊ณ ...
๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ๋ฒ์ ๋๋กญ๋ฐ์ค ๊ฐ์ ์ผ๋ฐ์ฌ์ฉ์์ฉ ํด๋ผ์ฐ๋์ ํฐ ์ฐจ์ด๋ ์๋ค.
ํด๋๋ ๋ง๋ค๊ณ

ํ์ผ๋ ์ฌ๋ฆฌ๊ณ

๋ค์ด๋ฐ๊ฑฐ๋ ๋ณด๊ณ ..

์ด๋ฐ ์ผ์์ ์ธ ๊ฒ๋ค์ ์์ธํ ์ค๋ช ์์ด๋ ๋์ถฉ ์ฌ์ฉํ ์ ์์ผ๋ฆฌ๋ผ ์๊ฐํ๋ค.
์ด์ ๋๋ค๋ฅผ ํตํด ํ๋ฒ S3์ ์ ๊ทผํ๊ณ , ์ ๋ก๋๋ฅผ ์ํํด๋ณด๋๋ก ํ๊ฒ ๋ค.
Lambda๋ก S3์ ์ ๋ก๋ํ๊ธฐ (Node.js)
์ผ๋จ ํจ์๋ฅผ ํ๋ ๋ง๋ค์ด๋ณด๊ฒ ๋ค.

๊ทธ๋ฆฌ๊ณ ์ธ๋ถ์์ ์ ์ํ ์ ์๊ฒ ๊ฒ์ดํธ์จ์ด๋ ๋์ถฉ ๋ฌ์์ค๋ค.

๋, S3์ ์ก์ธ์คํ ์ ์๋๋ก ๊ถํ๋ ๋ถ์ฌํด์ฃผ์
์คํ ์ญํ ์ ๋ค์ด๊ฐ
์ ์ฑ ์ฐ๊ฒฐ

s3 ๊ถํ์ ์ฐ๊ฒฐํด์ค๋ค.
๊ทธ๋ฆฌ๊ณ ๊ท์ฐฎ์ ๋ฉํฐํํธ ํ์ฑ์์
์ ์ฒ๋ฆฌํด์ค lambda-multipart-parser ๋ชจ๋์ ๋ ์ด์ด๋ก ๋ถ์ฌ์ค๋ค.
๊ทธ๋ผ ๋ฐ์์ ์ ๋์ถฉ ๋ ๊ฒ์ด๋ค.
์๋ฒ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ ์์ผ๋ก ์งค ์ ์๋ค.
upload ํจ์์ ํ์ผ๋ช
(Key)๊ณผ ๋ฒํท๋ช
(Bucket), ํ์ผ๋ฐ์ดํฐ(Body), ์ ๊ทผ ๊ถํ(ACL)์ ์ง์ ํด์ ํธ์ถํ๋ฉด ๋๋ค.
const aws = require('aws-sdk');
const s3 = new aws.S3();
const parser = require('lambda-multipart-parser');
exports.handler = async (event) => {
const {files} = await parser.parse(event);
console.log('## ํ์ผ');
console.log(files);
const result = await s3.upload({
Key: `/public/${Date.now()}.jpg`, // ํ์ผ path
Bucket: 'boom-bucket', // ๋ฒํท๋ช
Body: files?.[0]?.content, // ํ์ผ ๋ฐ์ดํฐ
ContentEncoding: "base64", // ํ์ผ์ ์ธ์ฝ๋ฉ ํ์. (๋๋ค๋ ๋ญ๋ base64๋ก ๋ฐ์์ด)
ContentType: "image/jpeg",
ACL: 'public-read', // ์ฝ๊ธฐ๋ ํผ๋ธ๋ฆญ
}).promise();
const response = {
statusCode: 200,
body: JSON.stringify(result),
};
return response;
};
๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ ์กฐ๊ธ ๊ท์ฐฎ์๋๊ฒ, ์ด๋ฏธ์ง๋ฅผ ๋ฐ์ ๋ฉํฐํํธ ๋ฐ์ดํฐ๋ฅผ ๋๋ค์์ ์ข ๋ถํธํ๊ฒ ๋ฐ์์จ๋ค๋ ๊ฒ์ด๋ค.
๋ชฝ๋
base64๋ก ๋ฐ๋๋ฐ๋ค ํ์ฑํ๊ธฐ๋ ์ข ๊ท์ฐฎ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ lambda-multipart-parser๋ฅผ ๋์ถฉ ๊ฐ๋ค์ผ๋ค.
๊ทธ๋ฆฌ๊ณ ์ ๋ก๋ ํ์ด์ง ์ฝ๋๋ค. ๋ณ๊ฑฐ์๋ค.
<html>
<script>
</script>
<body>
<h1>ํ
์คํธ</h1>
<form action="https://qdx7bkukn8.execute-api.ap-northeast-2.amazonaws.com/default/s3_test" method="POST" enctype="multipart/form-data">
<input type="file" name="image">
<button>ํ์ผ ์ ์ก</button>
</form>
</body>
</html>
์ ๊ฑธ๋ก ํ์ผ์ ์ฒจ๋ถํ๊ณ ์ ๋ก๋๋ฅผ ์๋ํ๋ฉด

์ฌ๋ผ๊ฐ๋ค๊ณ ํ์ผ๊ฒฝ๋ก๋ฅผ ๋๋ ค์ค ๊ฒ์ธ๋ฐ

S3์ ๊ฐ๋ ์ง์ ํ๋๋ก ์ ์ฌ๋ผ๊ฐ์์ ๊ฒ์ด๋ค.

๋๋

์ฐธ์กฐ
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
https://stackoverflow.com/questions/27980612/converting-base64-to-blob-in-javascript/27980815
https://www.npmjs.com/package/lambda-multipart-parser