s3Client.getUrl(bucket, uploadPathFile).toString();
S3 버킷에 이미지를 업로드하는 여러 방법이 있지만 스프링부트에서 AWS 서비스에 관련한 의존성을 추가 한 뒤 기본적으로 다른 설정 없이 이미지를 업로드하는 방법을 작성하려고 한다.
설정하거나 업로드 하는 코드 자체는 다른 인터넷 글을 참고하였다.
기본적으로 스프링부트의 API 엔드포인트에서 MultiPartFile을 입력받아 저장하는 것으로 가정한다.
1. 의존성 추가:
일단 의존성을 추가 해 준다 ( gradle 기준 )
// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-aws
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
2. AmazonConfig 설정 추가:
리전과 credential 설정이다. 기본적으로 설정해야 하는 내용만 추가한다.
@Configuration
public class AmazonConfig {
@Value("${cloud.aws.credentials.access-key}")
private String accessKey;
@Value("${cloud.aws.credentials.secret-key}")
private String secretKey;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
public AmazonS3 amazonS3() {
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region)
.build();
}
}
필요한 값은 모두 환경변수화 하였다.
cloud:
aws:
credentials:
access-key: ${AMAZON_ACCESS_KEY}
secret-key: ${AMAZON_SECRET_KEY}
s3:
bucket: ${AMAZON_S3_BUCKET}
region:
static: ${AMAZON_REGION}
stack:
auto: false
extends:
cloud:
aws:
s3:
bucket-url: ${AMAZON_S3_BUCKET_URL}
AWS 관련 라이브러리의 기능을 사용하기 위해서는 credential을 부여받아서 환경변수로 주입 후 설정해야 한다.
3. AWS Credential 정보 확인:
credential 정보를 확인하기 위해서는 IAM 서비스 내의 보안 자격 증명에 진입해야 한다.

아래에 Access Key 만들기를 통해 Access Key 를 생성한다.

생성 이후 비밀번호는 한 번밖에 확인이 불가능하니 다른 곳에 저장하거나 csv 파일 다운로드를 할 필요가 있다.

4. 이미지 업로드 서비스 메소드 생성:
AWS 의존성을 통해 버킷 관련 객체를 다루기 위한 s3Client는 상단의 설정을 통해 @Bean 설정 이후 @Autowired를 통해 주입받아 사용할 수 있다.
@Autowired
private AmazonS3 s3Client;
MultiPartFile, 저장 경로, 저장 파일 명을 파라메터로 받아 s3Client 객체를 사용 해 파일을 저장하고 저장 경로를 반환하는 서비스 메소드의 예시는 다음과 같다.
public String uploadImage(String prefixPath, String imageName, MultipartFile multipartFile) {
byte[] bytes = new byte[0];
try {
bytes = IOUtils.toByteArray(multipartFile.getInputStream());
} catch (IOException e) {
throw new // ~~
}
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
ObjectMetadata metadata = new ObjectMetadata();
String fileExtension = StringUtils.getFilenameExtension(multipartFile.getOriginalFilename());
String uploadPathFile = prefixPath + "/" + imageName;
if (fileExtension.equalsIgnoreCase("jpg") || fileExtension.equalsIgnoreCase("jpeg")) {
metadata.setContentType(MediaType.IMAGE_JPEG_VALUE);
}
else if (fileExtension.equalsIgnoreCase("png")) {
metadata.setContentType(MediaType.IMAGE_PNG_VALUE);
}
else throw new // ~~
metadata.setContentLength(bytes.length);
s3Client.putObject(new PutObjectRequest(bucket, uploadPathFile, byteArrayInputStream, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
return s3Client.getUrl(bucket, uploadPathFile).toString();
}
이미지를 저장하는 저 부분
s3Client.putObject(new PutObjectRequest(bucket, uploadPathFile, byteArrayInputStream, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
이 있고,
저장한 이미지의 버킷 url을 응답받는
s3Client.getUrl(bucket, uploadPathFile).toString();
를 잘 사용하면 된다.
이미지를 저장하는 putObject에서 bucket 명을 인자로 받는데, 환경변수화 된 버킷 명으로 들어갈 것이다.
이 때 필요한 S3 버킷을 잘 생성해보자.
5. S3 버킷 생성 및 설정:
S3 버킷 만들기를 통해 버킷을 생성한다.

별다른 보안 설정을 추가하지 않을 거라면 ACL 자체는 그대로 두고
아래 퍼블릭 액세스 차단에 대한 설정을 해제하여 접근이 기본적으로 가능하도록 설정한다.

기타 다른 설정은 추가적으로 하고 싶으면 하고, 버킷을 생성한다.
환경 변수에서 사용하는 버킷명은 버킷을 생성할 때 사용한 버킷명 그대로 (test) 삽입하면 된다.
하지만 퍼블릭 액세스 설정을 제외하고도, 버킷 자체에 버킷 정책이 따로 있어서, 여기서 추가로 권한 설정을 추가해야만 실제로 버킷에 업로드 한 이미지에 대한 접근이 가능하다.
버킷 설정의 권한 탭에서

json 으로 설정할 수 있는 버킷 정책 란이 존재한다.

aws 내 설정은 수만가지고, 설정하는 json 문법이나 객체명도 다 알지 못하기에, 편집을 누르고

새 구문 추가를 누르면

자동으로 내용이 채워지며 서비스를 고르라고 나온다.
S3를 선택, getObject를 찾아 체크하면

아래와 같이 설정이 자동으로 기입된다.

getObject (기본적인 읽기 권한)을 제외하고 다른 권한에 대한 정책도 추가하고 싶다면 같은 방법으로 추가하면 된다.
하지만 정책은 존재하는데 접근 가능한 리소스가 없으면 안되므로, 다시 왼쪽의 리소스 추가를 눌러

하단처럼 설정한다.

S3의 특정 오브젝트의 버킷명(jaehan1346)에 대한 모든 오브젝트 (*)로 설정하여 리소스 추가를 한다.
이 상태로 그냥 저장 시 오류가 날 수 있는데, 다른 문법이나 속성에 대한 것은 절차를 다시 밟아보고,
아래와 같이 principal에 관련한 오류라면

정책 내 Principal설정이
"Principal": {},
과 같이 설정되어 있다면 다음과 같이 바꿔준다.
"Principal": "*",
저장이 잘 되었다면 오류가 없는 것이다.
6. 파일 (이미지) 업로드
실제로 API를 호출하여 버킷에 업로드 후 사용하면 된다.