처음에는 프론트 분이 만든 버켓에 권한 가진 계정 만들어줘서 거기다가 시도했다가 계속 access denied 떠서 그냥 일단 내가 다시 S3 직접 만들어서 또 몇시간 동안 access denied 당하다가 겨우 성공.
AccessDenied: Access Denied
at Request.extractError (C:\projects\mypet-back\node_modules\aws-sdk\lib\services\s3.js:711:35)
at Request.callListeners (C:projects\mypet-back\node_modules\aws-sdk\lib\sequential_executor.js:106:20)
at Request.emit (C:\projects\mypet-back\node_modules\aws-sdk\lib\sequential_executor.js:78:10)
at Request.emit (C:\projects\mypet-back\node_modules\aws-sdk\lib\request.js:686:14)
at Request.transition (C:\projects\mypet-back\node_modules\aws-sdk\lib\request.js:22:10)
at AcceptorStateMachine.runTo (C:\projects\mypet-back\node_modules\aws-sdk\lib\state_machine.js:14:12)
at C:\projects\mypet-back\node_modules\aws-sdk\lib\state_machine.js:26:10
at Request.<anonymous> (C:\projects\mypet-back\node_modules\aws-sdk\lib\request.js:38:9)
at Request.<anonymous> (C:\projects\mypet-back\node_modules\aws-sdk\lib\request.js:688:12)
at Request.callListeners (C:\projects\mypet-back\node_modules\aws-sdk\lib\sequential_executor.js:116:18) {
code: 'AccessDenied',
region: null,
@ 모든 권한을 다 가졌는데도 왜 access가 거부될까. 이건 내가 직접 aws 사이트에서 업로드, 삭제는 되는데 vscode에서 aws-sdk를 통해서 하려고 하니까 거부하는 것이므로 권한 문제는 아닐 것이다.
어떤 외부에서의 접근을 차단하는 설정을 변경해줘야 한다는 것이었다.
@ 일단 AWS에서
IAM - 사용자 - 사용자 추가를 해서
ACCESS KEY와 SECRET KEY를 받아야 한다.
이 값들은 .env 파일에 환경변수로 입력해 줬다.
이거만들 때 s3fullaccess 도 줬던가. 암튼 다른거면 이거도 해줘야함.
그리고
버켓 - 권한으로 와서 엄청 여러가지를 설정해줘야 겨우 되는 듯 하다.
모든 퍼블릭 액세스 차단도 비활성화하고
버킷 정책에
{
"Version": "2012-10-17",
"Id": "Policy1660754391470",
"Statement": [
{
"Sid": "Stmt1660754379771",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::버켓이름"
},
{
"Sid": "S3PolicyStmt-DO-NOT-MODIFY-1660770723586",
"Effect": "Allow",
"Principal": {
"Service": "logging.s3.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::버켓이름/*"
}
]
}
이런 것도 적어주고. 이거 aws 사이트 어디서 policy generator? 같은 기능으로 뭐뭐 선택하니까 작성해줬던 거로 기억. 아니어도 이거 복붙하면 됨 이제.
그 밑에 ACL 까지 모든 권한 주도록 설정 바꿔줬던 거로 기억.
아 그리고 버킷 소유자 적용도 비활성화 해야함.
const aws = require("aws-sdk");
require("dotenv/config");
const PostRepository = require("../layers/repositories/post.repository");
module.exports = s3Delete = async (req, res, next) => {
try {
const postRepository = new PostRepository();
const s3 = new aws.S3({
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY,
region: process.env.S3_REGION,
});
const imageUrl = await postRepository.getUrlById(req.params.postId);
console.log(imageUrl.imageUrl);
const bucketname = process.env.S3_BUCKET_NAME;
s3.deleteObject(
{
Bucket: bucketname,
Key: imageUrl.imageUrl,
},
(err, data) => {
if (err) {
console.error(err);
console.log(data);
} else {
console.log("이미지 삭제 성공");
}
}
);
res.locals.success = true;
next();
} catch (err) {
res.locals.success = false;
next();
}
};
여기서 Key라는 거는 버켓에서의 '경로/파일이름'이다.
난 폴더를 안만들었기에 그냥 파일이름이 key가 된다.
앞으로 프론트는 s3에 이미지를 업로드 후 그 파일의 이름을 요청시 넘겨줘야하고
우리는 그걸 DB에 저장했다가 게시글 삭제 시 그 파일 이름을 가지고
위 코드를 호출하여 s3에서 삭제해 주어야 한다.
https://artiiicy.tistory.com/16
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObject-property //참고는 별로안된거 같지만 공식문서