Web & Mobile/AWS

[AWS] IAM을 이용한 S3 서버 파일 업로드 (Springboot)

byunghyun23 2022. 11. 9. 20:53

Springboot에서 S3 서버에 파일을 업로드하는 방법입니다.

 

1. AWS에서 'IAM' 검색

 

2. 사용자 > 사용자 추가 클릭

 

3. 사용자 이름 입력 및 AWS 자격 증명 유형 선택(액세스 키 - 프로그래밍 방식 액세스)

4. 권한 설정에서 기존 정책 직접 연결 및 정책 선택(AmazonS3FullAccess)

 

5. 태그 생략 및 검토 과정 후 생성된 액세스 키를 csv로 저장(나중에 필요)

 

6. Springboot 설정

다운로드 받은 csv를 참조하여 application.properties에 다음과 같이 작성

spring.servlet.multipart.max-file-size: 100MB
spring.servlet.multipart.max-request-size: 100MB
cloud.aws.region.static=ap-northeast-2
cloud.aws.stack.auto=false

ima.access.key=액세스키값
ima.secret.key=시크릿키값
ima.region=ap-northeast-2
ima.s3.bucket=버킷명

아래와 같이 pom.xml에 dependency 추가

<dependencies>
    <!-- AWS -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-aws</artifactId>
        <version>2.2.6.RELEASE</version>
    </dependency>		
</dependencies>

 

AWS 설정 클래스를 다음과 같이 생성

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

@Configuration
public class AWSConfig {
	
	@Value("${ima.access.key}")
	private String iamAccessKey;
	@Value("${ima.secret.key}")
	private String iamSecretKey;
	@Value("${ima.region}")
	private String region; 
	
	@Bean
	public AmazonS3Client amazonS3Client() {
		BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(iamAccessKey, iamSecretKey);
		
		return (AmazonS3Client) AmazonS3ClientBuilder.standard().withRegion(region)
				.withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials)).build();
	}
}

관련 컨트롤러 작성

@RestController
public class FileController {
	
	
	@Value("${ima.s3.bucket}")
	private String S3Bucket; // Bucket 이름 
	
	
	@Autowired
	AmazonS3Client amazonS3Client;
	
	@PostMapping("/upload")
	public ResponseEntity<Object> upload(@RequestParam("files") MultipartFile[] multipartFileList) throws Exception {
		List<String> imagePathList = new ArrayList<>();
		
		for(MultipartFile multipartFile: multipartFileList) {
			String originalName = multipartFile.getOriginalFilename(); // 파일 이름
			long size = multipartFile.getSize(); // 파일 크기
			
			ObjectMetadata objectMetaData = new ObjectMetadata();
			objectMetaData.setContentType(multipartFile.getContentType());
			objectMetaData.setContentLength(size);
			
			// S3에 업로드
			amazonS3Client.putObject(
				new PutObjectRequest(S3Bucket, originalName, multipartFile.getInputStream(), objectMetaData)
					.withCannedAcl(CannedAccessControlList.PublicRead)
			);
			
			String imagePath = amazonS3Client.getUrl(S3Bucket, originalName).toString(); // 접근가능한 URL 가져오기
			imagePathList.add(imagePath);
		}
		
		return new ResponseEntity<Object>(imagePathList, HttpStatus.OK);
	}
}

 

view page에서 form으로 이미지 또는 파일을 upload 컨트롤러로 넘겨주시면 됩니다.

 

 

추가로 AWS 버킷 권한 > 객체 소유권 > ACL 활성화됨 설정을 해야 정상적인 업로드가 가능합니다.