Cross-Origin-Resource-Sharing 의 줄임말로, 교차 출처 리소스 공유 라는 뜻이다.
사진 출처 : CORS의 기본 개념과 동작 방식(부제: Preflight 요청이란?)
(Origin)이 다르면 발생하는 브라우저 정책cross-origin은 다음 중 한가지라도 다른 경우를 말함. 이 셋 중 하나라도 다르면 CORS 가 발생한다.
http / https 두 프로토콜은 다르다.localhost / naver.com 두개는 다르다.8080 / 3000은 다르다.프로젝트 하면 Backend는 Java Spring으로 개발하고 Frontend를 React로 개발할 때
REST API 형태로 개발할 것이다.
HTTP 통신을 하게 되면 Spring의 톰캣은 localhost:8080 / React : localhost:3000 으로 다르다.
이때 서버로 데이터를 요청해야 하는데, 이때 CORS가 발생할 가능성이 높다.
- Simple Request : 단순 요청
- Preflight Request : 예비 요청
- Credential Request : 인증된 요청
단순히 요청을 보내는 방법이다.
Client가 요청을 보내면 Server는 Access-Control-Allow-Origin을 헤더에 붙여 Response를 한다.
그럼 Access-Control-Allow-Origin를 판단하여 CORS를 검사한다.
❗ Access-Control-Allow-Origin : 서버에서 허용된 Origin

사진 출처 : CORS의 기본 개념과 동작 방식(부제: Preflight 요청이란?)
위 사진은 Access-Control-Allow-Origin : * 으로 설정되어 있으니,
모든 도메인을 허가하겠다는 뜻이다.
아래 상황을 한번 보겠다.
- 요청한 Client :
1.2.3.4:8080- Server의
Access-Control-Allow-Origin:a.com
Client의 도메인과 Server가 허용한 도메인은 서로 다르다.
이 상황에서 HTTP 응답은 200 OK이지만 ❗ CORS 정책이 발생한다!

GET, HEAD 요청Content-Type 헤더가 다음과 같은 POST 요청application/x-www-form-urlencodedmultipart/form-datatext/plainAccept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안됨.하지만 나는 REST API의 형태로 Content-Type이 application/json이기 때문에 Preflight로 처리 된다.
서버에 예비 요청을 보내는 것, Preflight 요청을 받아서 비교하고, 허가되지 않은 요청이면 CORS 발생
미리 이 예비 요청은 OPTIONS 방식으로 보낸다.
만약 CORS가 걸리는 요청인데 API 호출하면 불필요한 리소스를 낭비하기에 예비 요청을 통해서 불필요한 리소스를 줄이는 것이다.

인증정보를 포함한 요청, 보안을 강화하고 싶을 때 헤더에 인증 정보를 넣어 보내는 방식.
Access-Control-Allow-Credentials : true 를 추가한다.Access-Control-Allow-Origin 을 정확하게 설정한다. * 로 설정 X나의 경우에는 JWT 토큰을 담아 보안을 강화했다.
헤더에 Authorization에 토큰을 담아 요청을 보낸다.

여기서는 간단하게 세팅할 수 있는 방법으로 살펴보겠다. 모든 도메인을 허가하는 방식이다.
본인에게 필요하게 변경하여 사용하면 되겠다.
setAllowCredentials:false➜ Credentials 방식 사용 안함setAllowOrigins(Arrays.asList("*"));: 모든 도메인 허용setAllowedMethods: 허가할 메소드들setAllowedHeaders: HTTP 통신에서 허가할 헤더들
package -
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
import java.util.List;
@Configuration
public class CorsConfig {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(false);
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
config.setExposedHeaders(List.of("Authorization","Content-Type", "Accept"));
config.setAllowedHeaders(List.of("Authorization","Content-Type", "Accept"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
환경
1. Client : Reactlocalhost:3000
2. Server : AWS EC21.2.3.4:8080
3. Spring Boot v3.1.5
아마 잘 된다. 더 큰 문제는 다음 화에 이어진다.
기타
Postman은 CORS를 발생시키지 않으니, 꼭 실제 React나 브라우저에서 테스트해보길 권유한다.
나도 Postman에서는 정상 작동하는데, 브라우저로 가거나 React에서 요청하면 그때 CORS가 발생한다.
