AWS S3 버킷 생성



내 pc로 접근할 것이기 때문에 모든 퍼블릭 액세스 차단 해제



나머지 설정은 건드리지 않음

버킷이 생성되었다

유저의 프로필 사진들을 저장할 profile_imgs 폴더를 만들어준다
IAM 만들기




사용자 생성 완료

IAM accessKey, secretKey 얻기
IAM - 사용자 - 보안 자격 증명
액세스 키 만들기




버킷 접근 권한 설정
코드를 다 알맞게 작성했는데 이미지가 안불러와져서 알아보니 버킷에 getobject가 가능하도록 권한을 설정해줘야 했다!

나의 버킷에서 권한 정책을 이렇게 수정하였다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::talenttreebucket/*"
}
]
}

S3Config
package com.springboot.portfolio.config;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class S3Config {
@Value("${cloud.aws.credentials.accessKey}")
private String accessKey;
@Value("${cloud.aws.credentials.secretKey}")
private String secretKey;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
public AmazonS3 amazonS3() {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region)
.build();
}
}
application.properties
spring.profiles.include=private
이렇게 지정해놓고 s3에 관한 설정들은 application-private.properties 에 저장해놓았다.
private 설정들은 민감하므로 gitignore에 추가해놓았다.
application-private.properties
# S3
cloud.aws.credentials.accessKey={your-access-key}
cloud.aws.credentials.secretKey={your-secret-key}
cloud.aws.s3.bucketName={your-bucket-name}
cloud.aws.region.static={your-region}
cloud.aws.stack.auto-=false
LoginController
기존 사용자의 정보 수정 시 이미지를 업로드하는 controller에서
local 서버에 이미지를 저장하는 방식에서 s3에 이미지를 업로드 하는 방식으로 수정하였다.
@Controller
@RequiredArgsConstructor
public class LoginController {
// private static String UPLOAD_DIR = System.getProperty("user.dir") + "/src/main/resources/static/bootstrap/assets/uploads";
private final AmazonS3 amazonS3;
@Value("${cloud.aws.s3.bucketName}")
private String bucket;
private String folderName = "profile_imgs/";
private final UserService userService;
@GetMapping("/addinfo")
public String calladdinfo(Model model, HttpSession session) throws Exception {
User newUser = (User) session.getAttribute("logined");
String userId = newUser.getUser_id();
User userinfo = userService.findById(userId);
model.addAttribute("userinfo",userinfo);
return "addinfo";
}
@PostMapping(value="/addinfo", consumes = "multipart/form-data")
public String processAddInfo(@ModelAttribute("userInfo") UserRequestDto userDto, @RequestParam("img") MultipartFile file, HttpSession session, RedirectAttributes attributes) throws Exception {
User loginedUser = (User) session.getAttribute("logined");
// 업데이트된 정보로 사용자 정보 업데이트
loginedUser = userService.updateUserInfo(loginedUser.getUser_id(), userDto.getFull_name(), userDto.getGithub(), userDto.getBlog());
String fileName = null;
// Check if file is empty
if (file.isEmpty()) {
attributes.addFlashAttribute("message", "Please select a file to upload.");
session.setAttribute("logined", loginedUser);
} else {
fileName = file.getOriginalFilename();
// Path path = Paths.get(UPLOAD_DIR, fileName);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
metadata.setContentType(file.getContentType());
// 폴더명을 포함한 객체 키 설정
String key = folderName + fileName;
amazonS3.putObject(bucket, key, file.getInputStream(), metadata);
/*
// Save the file on server
try {
Files.createDirectories(path.getParent());
Files.copy(file.getInputStream(), path);
} catch (IOException e) {
e.printStackTrace();
}
*/
String imgUrl = amazonS3.getUrl(bucket, key).toString();
loginedUser = userService.updateUserImage(loginedUser.getUser_id(), imgUrl);
session.setAttribute("logined", loginedUser);
}
return "redirect:/index";
}
}
IndexFrontController
@Controller
public class IndexFrontController {
private final UserService userService;
private HttpSession httpSession;
private final AmazonS3 amazonS3;
@Value("${cloud.aws.s3.bucketName}")
private String bucket;
public IndexFrontController(UserService userService, HttpSession httpSession, AmazonS3 amazonS3) {
this.userService = userService;
this.httpSession = httpSession;
this.amazonS3 = amazonS3;
}
@GetMapping("/index")
public String getUserInfo(Model model) throws Exception {
User newUser = (User) httpSession.getAttribute("logined");
if (newUser!=null){
String userId = newUser.getUser_id();
User user = userService.findById(userId);
/*
// 이미지 파일 경로 설정
String url = amazonS3.getUrl(bucket, filename).toString();
String imgPath = user.getImage() != null ? "/bootstrap/assets/uploads/" + user.getImage() : "";
user.setImage(imgPath);
*/
String fileName = user.getImage();
if (fileName != null && !fileName.isEmpty()) {
user.setImage(fileName);
}
model.addAttribute("user",user);
return "index";
}
else{
return "unloginedindex";
}
}
}
index와 같은 로직으로 project 코드들도 수정하였다.
ProjectFrontController
@Controller
@RequestMapping("/projects")
public class ProjectFrontController {
//private static String UPLOAD_DIR = System.getProperty("user.dir") + "/src/main/resources/static/bootstrap/assets/project_uploads";
private final AmazonS3 amazonS3;
@Value("${cloud.aws.s3.bucketName}")
private String bucket;
private String folderName = "project_imgs/";
private final ProjectService projectService;
public ProjectFrontController(AmazonS3 amazonS3, ProjectService projectService) {
this.amazonS3 = amazonS3;
this.projectService = projectService;
}
@GetMapping()
public String getProject(Model model, HttpSession session) {
if (session.getAttribute("logined") != null) {
List<ProjectDto> projects = projectService.findByUserId();
for (ProjectDto projectDto : projects) {
String imgPath = projectDto.getImg() != null ? projectDto.getImg() : "";
projectDto.setImg(imgPath);
}
Collections.reverse(projects);
model.addAttribute("projects", projects);
return "projects";
} else {
return "needlogin";
}
}
@PostMapping(value="/add", consumes = "multipart/form-data")
public String addProject(@ModelAttribute("project") ProjectFrontRequestDto projectFrontRequestDto, @RequestParam("img") MultipartFile file) throws Exception {
String fileName = null;
ProjectRequestDto projectRequestDto = new ProjectRequestDto();
projectRequestDto.setName(projectFrontRequestDto.getName());
projectRequestDto.setRole(projectFrontRequestDto.getRole());
projectRequestDto.setDescription(projectFrontRequestDto.getDescription());
projectRequestDto.setSkill_list(projectFrontRequestDto.getSkill_list());
projectRequestDto.setGithub(projectFrontRequestDto.getGithub());
projectRequestDto.setStart_date(projectFrontRequestDto.getStart_date());
projectRequestDto.setEnd_date(projectFrontRequestDto.getEnd_date());
if(!file.isEmpty()) {
fileName = file.getOriginalFilename();
/*
// Normalize the file path
Path path = Paths.get(UPLOAD_DIR, fileName);
// Save the file on server
try {
Files.createDirectories(path.getParent());
Files.copy(file.getInputStream(), path);
} catch (IOException e) {
e.printStackTrace();
}
*/
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
metadata.setContentType(file.getContentType());
// 폴더명을 포함한 객체 키 설정
String key = folderName + fileName;
amazonS3.putObject(bucket, key, file.getInputStream(), metadata);
String imgUrl = amazonS3.getUrl(bucket, key).toString();
projectRequestDto.setImg(imgUrl);
}
projectService.createProject(projectRequestDto);
return "redirect:/projects";
}
@PostMapping(value="/update", consumes = "multipart/form-data")
public String updateProject(@ModelAttribute("project") ProjectFrontUpdateReqDto projectReqDto, @RequestParam("img") MultipartFile file) throws Exception {
System.out.println("hihi");
String fileName = null;
ProjectDto projectDto1 = new ProjectDto();
projectDto1.setProject_id(projectReqDto.getProject_id());
projectDto1.setName(projectReqDto.getName());
projectDto1.setRole(projectReqDto.getRole());
projectDto1.setDescription(projectReqDto.getDescription());
projectDto1.setSkill_list(projectReqDto.getSkill_list());
projectDto1.setGithub(projectReqDto.getGithub());
projectDto1.setStart_date(projectReqDto.getStart_date());
projectDto1.setEnd_date(projectReqDto.getEnd_date());
if(!file.isEmpty()) {
fileName = file.getOriginalFilename();
/*
// Normalize the file path
Path path = Paths.get(UPLOAD_DIR, fileName);
// Save the file on server
try {
Files.createDirectories(path.getParent());
Files.copy(file.getInputStream(), path);
} catch (IOException e) {
e.printStackTrace();
}
*/
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
metadata.setContentType(file.getContentType());
// 폴더명을 포함한 객체 키 설정
String key = folderName + fileName;
amazonS3.putObject(bucket, key, file.getInputStream(), metadata);
String imgUrl = amazonS3.getUrl(bucket, key).toString();
projectDto1.setImg(imgUrl);
}
projectService.updateProject(projectDto1);
return "redirect:/projects"; // Redirect to avoid form resubmission
}
}