이번엔 공통단 세팅을 해본당
저번시간에 api만들어서 프론트담당 친구들에게 request날려 보라했더니 오류가 난다고한다..
has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource
해당 오류는 cors 정책 위반이라고 하네 생각해보니 실무에서 하이브리드 모바일용 api개발당시 접했던 오류랑 동일하다.
cors와 관련된 내용은 구글링해서 이론을 쫌 훑어봤는데 서버와 클라이언트의 리소스가 다른데 통신을 요청해와서 보안이슈가 발생할수 있어서 막아놨다고 정리하면 되려나...
이론도 이론인데 결국 서버에서 세팅을 해줘야 해결해야함 해결법은 난 글로벌 방법을 선택했다.
WebConfig.class
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*");
}
}
여기서 허용 메소드와 허용 클라이언트를 명시하면되는데 우선 와일드카드로 풀어놨다 나중엔 우리가 사용할 모바일과 웹 리소스로만 제한되도록 해야겠다.
이렇게 글로벌하게 설정하는 방법외에도
@CrossOrigin(origins="도메인1,도메인2")이런식으로 각 컨트롤러에 설정하는 방법도 있다고한다.
옵션을 안주고 어노테이션만 사용하면 와일드카드 전부허용이라넹
아무튼 이렇게 설정하고 깃허브에 push후 재배포하니 정상적으로 통신이 되었다.
@Component
@RequiredArgsConstructor
public class AmazonS3Component {
@Value("${cloud.aws.s3.bucket}")
private String bucket;
private final AmazonS3Client amazonS3Client;
public FileDto save(MultipartFile multipartFile) {
FileDto fileDto = FileDto.multipartOf(multipartFile);
String key = fileDto.getKey();
File file = new File(MultipartUtil.getLocalHomeDirectory(), key);
try {
multipartFile.transferTo(file);
amazonS3Client.putObject(new PutObjectRequest(bucket, key, file)
.withCannedAcl(CannedAccessControlList.PublicRead));
fileDto.setFileUrl(amazonS3Client.getUrl(bucket,multipartFile.getOriginalFilename()).toString());
} catch (Exception e) {
System.out.println(e.getMessage());
throw new RuntimeException();
} finally {
if (file.exists()) {
file.delete();
}
}
return fileDto;
}
public void delete(FileDto fileDto){
if (!amazonS3Client.doesObjectExist(bucket, fileDto.getKey())) {
throw new AmazonS3Exception("Object " +fileDto.getKey()+ " does not exist!");
}
amazonS3Client.deleteObject(bucket, fileDto.getKey());
}
}
다음은 aws s3 파일서버에 이미지를 저장시키는 공통로직이다.
@Value("${cloud.aws.s3.bucket}")
이부분은 storage.properties에서 가져와 읽는데 이건 예전에 한번 push했다가 아마존에 데여서 앞으로 블로그에 보여질일은 없을거같다. 이 컴포넌트도 스프링컨테이너에 빈으로 관리할거기때문에 @Component어노테이션을 붙여주었다. 이미지관련 로직에서 db에 저장할때야 각기다른테이블을 사용하겠지만 파일서버에 물리파일을 떨구고 지우는 로직은 전부 이 컴포넌트를 활용할 예정이다. 추후에 파라미터나 리턴타입은 수정될 수 있을 것 같다.
public class MultipartUtil {
private static final String BASE_DIR = "awsImages";
/**
* 로컬에서의 사용자 홈 디렉토리 경로를 반환합니다.
*/
public static String getLocalHomeDirectory() {
return System.getProperty("user.home");
}
/**
* 새로운 파일 고유 ID를 생성합니다.
* @return 36자리의 UUID
*/
public static String createFileId() {
return UUID.randomUUID().toString();
}
/**
* Multipart 의 ContentType 값에서 / 이후 확장자만 잘라냅니다.
* @param contentType ex) image/png
* @return ex) png
*/
public static String getFormat(String contentType) {
if (StringUtils.hasText(contentType)) {
return contentType.substring(contentType.lastIndexOf('/') + 1);
}
return null;
}
/**
* 파일의 전체 경로를 생성합니다.
* @param fileId 생성된 파일 고유 ID
* @param format 확장자
*/
public static String createPath(String fileId, String format) {
return String.format("%s/%s.%s", BASE_DIR, fileId, format);
}
}
요건 이미지파일과 관련된 유틸인데 static으로 쓰는거야 익숙하다. String,Math 등 유틸관련이 보통 그러니까.. 자주쓸텐데 new로 계속 인스턴스 만드는건 비효율적이다.
이제 프로젝트 초반에 필요한 세팅은 얼추 마무리되었는데 세팅도세팅인데
서버와 클라이언트가 분리되고 각기 다른사람이 하다보니 의사소통이 되게 중요한거 같다. 나만 신나서 파라미터 마음대로 설정하고 편한대로 데이터를 뿌리면 클라이언트 측에서 고생한다.. 앞으로 의사소통 및 api 명세에 신경을 많이 써야할 거같다
'Project > MangoPlate Clone' 카테고리의 다른 글
메인 목록에 QueryDsl 필터링 추가 (0) | 2023.02.17 |
---|---|
QueryDSL에서 mariaDB 위도 경도 계산 함수 호출 (0) | 2023.02.15 |
JPA Setting 및 Test (0) | 2023.02.14 |
MyBatis Setting 및 Test (0) | 2023.02.14 |
Project Detail Setting (0) | 2023.02.14 |