이번 글에서 node.js 환경에서 base64 이미지를 s3 버킷에 저장하는 코드를 설명하려고 합니다.
가장 먼저 aws-sdk를 설치가 필요합니다.
아래의 명령어를 통해서 패키지를 설치해줍니다.
npm install aws-sdk --save
nodejs에서 aws-sdk를 이용해서 s3에 접근하기 위해서는 다음과 같은 정보들이 기본적으로 필요합니다.
1. Access Key Id
2. Secret access Id
3. aws region
4. s3 bucket
우선 S3 버킷이 없다면 만들어줍니다. 버킷은 AWS의 S3 서비스 화면에서 만들 수 있습니다.
그 후, IAM을 만들어 s3에 대한 full access 권한을 부여주세요.
IAM을 만들면 ACCESS_KEY_ID, SECRET_ACCESS_KEY 를 발급받게 되는데, 이는 반드시 따로 저장해둡니다!
버킷을 만들면 아래같은 화면을 볼 수 있는데, 아래에서 region과 버킷 이름을 확인해주세요.
위의 정보들을 json파일이나 .env 파일에 따로 저장해둡니다.
이제 아래의 예제를 사용할 준비가 되었습니다.
/**
* This gist was inspired from https://gist.github.com/homam/8646090 which I wanted to work when uploading an image from
* a base64 string.
* Updated to use Promise (bluebird)
* Web: https://mayneweb.com
*
* @param {string} base64 Data
* @return {string} Image url
*/
const imageUpload = async (base64) => {
// You can either "yarn add aws-sdk" or "npm i aws-sdk"
const AWS = require('aws-sdk');
// Configure AWS with your access and secret key.
const { ACCESS_KEY_ID, SECRET_ACCESS_KEY, AWS_REGION, S3_BUCKET } = process.env;
// Configure AWS to use promise
AWS.config.setPromisesDependency(require('bluebird'));
AWS.config.update({ accessKeyId: ACCESS_KEY_ID, secretAccessKey: SECRET_ACCESS_KEY, region: AWS_REGION });
// Create an s3 instance
const s3 = new AWS.S3();
// Ensure that you POST a base64 data to your server.
// Let's assume the variable "base64" is one.
const base64Data = new Buffer.from(base64.replace(/^data:image\/\w+;base64,/, ""), 'base64');
// Getting the file type, ie: jpeg, png or gif
const type = base64.split(';')[0].split('/')[1];
// Generally we'd have an userId associated with the image
// For this example, we'll simulate one
const userId = 1;
// With this setup, each time your user uploads an image, will be overwritten.
// To prevent this, use a different Key each time.
// This won't be needed if they're uploading their avatar, hence the filename, userAvatar.js.
const params = {
Bucket: S3_BUCKET,
Key: `${userId}.${type}`, // type is not required
Body: base64Data,
ACL: 'public-read',
ContentEncoding: 'base64', // required
ContentType: `image/${type}` // required. Notice the back ticks
}
// The upload() is used instead of putObject() as we'd need the location url and assign that to our user profile/database
// see: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
let location = '';
let key = '';
try {
const { Location, Key } = await s3.upload(params).promise();
location = Location;
key = Key;
} catch (error) {
// console.log(error)
}
// Save the Location (url) to your database and Key if needs be.
// As good developers, we should return the url and let other function do the saving to database etc
console.log(location, key);
return location;
// To delete, see: https://gist.github.com/SylarRuby/b3b1430ca633bc5ffec29bbcdac2bd52
}
위의 코드에서 userId 부분은 파일 명을, type은 png와 같은 확장자 명을 의미합니다.
따라서 위의 코드를 실행시키면 "1.png"라는 파일이 s3에 생성됩니다.
만약 파일을 특정 폴더에 넣고싶다면, params의 key앞에 `examplefolder/${userId}.${type}` 와 같이 바꿔주면 됩니다.
정상적으로 수행되었다면, 함수로부터 https://s3.ap-northeast-2.amazonaws.com.~~ 와 같은 객체 URL이 리턴됩니다.
아래와 같이 적용할 수 있습니다.
app.post('/testapi', async function (req: any, res: any) {
res.send(await imageUpload(req.body.base64));
res.status(200);
});
'Node.js' 카테고리의 다른 글
[Node.js] 세션 정보 변경이 반영되지 않을 때 (2) | 2021.05.04 |
---|---|
[Node.js] 하드코딩 피하기, dotenv 사용법 (0) | 2021.03.18 |
[Node.js] rest api 파라미터에 한글 넣어 요청하기 (0) | 2021.03.12 |